{"id":64933,"date":"2007-05-04T21:58:00","date_gmt":"2007-05-04T21:58:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2007\/05\/04\/how-can-i-replace-single-quote-marks-in-a-text-file\/"},"modified":"2007-05-04T21:58:00","modified_gmt":"2007-05-04T21:58:00","slug":"how-can-i-replace-single-quote-marks-in-a-text-file","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/how-can-i-replace-single-quote-marks-in-a-text-file\/","title":{"rendered":"How Can I Replace Single Quote Marks in a Text File?"},"content":{"rendered":"<p><IMG class=\"nearGraphic\" title=\"Hey, Scripting Guy! Question\" height=\"34\" alt=\"Hey, Scripting Guy! Question\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" width=\"34\" align=\"left\" border=\"0\"> \n<P>Hey, Scripting Guy! I saw your column on <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/qanda\/feb05\/hey0208.mspx\"><B>replacing text in a text file<\/B><\/A>, and that\u2019s <I>almost<\/I> the solution I\u2019m looking for. However, the text I need to replace is the single quote mark, and I can\u2019t figure out how to do that. How do I replace single quote marks in a text file?<BR><BR>&#8212; JB<\/P><IMG height=\"5\" alt=\"Spacer\" src=\"https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/05\/spacer.gif\" width=\"5\" border=\"0\"><IMG class=\"nearGraphic\" title=\"Hey, Scripting Guy! Answer\" height=\"34\" alt=\"Hey, Scripting Guy! Answer\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" width=\"34\" align=\"left\" border=\"0\"><A href=\"http:\/\/go.microsoft.com\/fwlink\/?linkid=68779&amp;clcid=0x409\"><IMG class=\"farGraphic\" title=\"Script Center\" height=\"288\" alt=\"Script Center\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/ad.jpg\" width=\"120\" align=\"right\" border=\"0\"><\/A> \n<P>Hey, JB. You know, this is shaping up to be another very hectic day for the Scripting Guys; after all, we have meetings in the morning as well as meetings in the afternoon. That would be bad enough, but these meetings also involve such heavy-duty issues as our budget for the coming year and the new system that we will eventually have to use in order to manage the Script Center. And yet, as busy as he is, there\u2019s still one thing that remains first and foremost in the mind of the Scripting Guy who writes this column: what <I>should<\/I> he have for dinner tonight?<\/P>\n<P>Maybe chicken casserole; the Scripting Family hasn\u2019t had chicken casserole in awhile. And maybe \u201ccandied carrots,\u201d you know, the ones with the butter and the brown sugar glaze on them. Or maybe \u2026.<\/P>\n<P>To be honest, JB, this could take awhile; after all, important decisions like this should never be made lightly. While you wait, feel free to read a magazine. If you don\u2019t happen to have a magazine handy, then feel free to read the following script, one that replaces all the single quote marks in a text file. In fact, not only does it replace the single quote marks, but it replaces them with <I>double<\/I> quote marks!<\/P>\n<P>OK, sure, that <I>sounds<\/I> impossible. But the proof, as they say, is in the pudding.<\/P>\n<P>Hmmm, pudding might be good, too \u2026.<\/P>\n<P>Here\u2019s the script:<\/P><PRE class=\"codeSample\">Const ForReading = 1\nConst ForWriting = 2<\/p>\n<p>Set objFSO = CreateObject(&#8220;Scripting.FileSystemObject&#8221;)\nSet objFile = objFSO.OpenTextFile(&#8220;C:\\Scripts\\Test.txt&#8221;, ForReading)<\/p>\n<p>strText = objFile.ReadAll\nobjFile.Close<\/p>\n<p>strOldText = Chr(39)\nstrNewText = Chr(34)<\/p>\n<p>strNewText = Replace(strText, strOldText, strNewText)<\/p>\n<p>Set objFile = objFSO.OpenTextFile(&#8220;C:\\Scripts\\Test.txt&#8221;, ForWriting)\nobjFile.WriteLine strNewText\nobjFile.Close\n<\/PRE>\n<P>What we\u2019re assuming here is that we have a text file that looks something like this:<\/P><PRE class=\"codeSample\">&#8216;Ken Myer&#8217;,&#8217;Finance&#8217;,&#8217;Senior Analyst&#8217;\n&#8216;Pilar Ackerman&#8217;,&#8217;Human Resources&#8217;,&#8217;Manager&#8217;\n&#8216;Jonathan Haas&#8217;,&#8217;Transportation&#8217;,&#8217;Director&#8217;\n<\/PRE>\n<P>All we want to do is replace all the single quote marks with double quote marks. As JB has discovered, however, that\u2019s not quite as easy as it sounds. Why not? We\u2019ll explain that in a moment. Before we do that, however, let\u2019s talk about the first part of the script.<\/P>\n<P>As you can see, we kick things off by defining a pair of constants (ForReading and ForWriting); we\u2019ll use these constants when we open our text file. (And yes, we <I>do<\/I> have to open the file twice: once to read in the existing contents, then once more to write out the new, revised contents.) After defining the constants we create an instance of the <B>Scripting.FileSystemObject<\/B>, then use the <B>OpenTextFile<\/B> method to open the file C:\\Scripts\\Test.txt for reading:<\/P><PRE class=\"codeSample\">Set objFSO = CreateObject(&#8220;Scripting.FileSystemObject&#8221;)\nSet objFile = objFSO.OpenTextFile(&#8220;C:\\Scripts\\Test.txt&#8221;, ForReading)\n<\/PRE>\n<P>What do we do with the file once it\u2019s open? For starters, we use the <B>ReadAll<\/B> method to read the entire file and store the contents in a variable named strText. And then we immediately turn around and close the file.<\/P>\n<TABLE class=\"dataTable\" id=\"EKE\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD class=\"\">\n<P class=\"lastInCell\"><B>Note<\/B>. Yes, that <I>does<\/I> seem sort of silly, doesn\u2019t it? However, the FileSystemObject will only let us open a file and read from it, <I>or<\/I> open a file and write to it; we can\u2019t carry out both operations at the same time. (Strange but true.) Having read from the file we have no choice but to close the thing before we\u2019ll be allowed to write to it.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>In a typical search-and-replace script this would be the point where we would call the VBScript <B>Replace<\/B> function and replace the single quote marks with double quote marks. We\u2019re guessing that JB has tried to do just that, using a line of code similar to this:<\/P><PRE class=\"codeSample\">strNewText = Replace(strText, &#8220;&#8216;&#8221;, &#8220;&#8221;&#8221;)\n<\/PRE>\n<P>Now, syntactically, that looks OK; after all, we\u2019ve called the Replace function followed by three parameters: <\/P>\n<TABLE class=\"\" cellSpacing=\"0\" cellPadding=\"0\" border=\"0\">\n<TBODY>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P><B>strText<\/B>, the text we want to do the search-and-replace operation on.<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P><B>&#8220;&#8216;&#8221;<\/B>, the single quote mark (embedded between a pair of double quote marks), representing the text to be replaced.<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P><B>&#8220;&#8221;&#8221;<\/B>, the double quote mark (embedded between a pair of double quote marks), representing the replacement text.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<P>Like we said, that <I>looks<\/I> OK. But here\u2019s what happens when we try to use this code:<\/P><PRE class=\"codeSample\">C:\\Scripts\\test.vbs(13, 40) Microsoft VBScript compilation error: Unterminated string constant\n<\/PRE>\n<P>Yikes! What\u2019s <I>that<\/I> all about?<\/P>\n<P>As you might have guessed, the problem is due to the fact that both the single quote mark and the double quote mark have special meanings in VBScript. The single quote mark, to name one use, indicates a comment added to a script:<\/P><PRE class=\"codeSample\">&#8216; This is a comment\n<\/PRE>\n<P>Meanwhile, the double quote mark is used \u2013 among other things \u2013 to enclose string values:<\/P><PRE class=\"codeSample\">x = &#8220;This is a string value.&#8221;\n<\/PRE>\n<P>Because these characters have special meanings, all we\u2019ve managed to do so far is to confuse VBScript. For example, a human being might look at three consecutive double quote marks and think, \u201cOh, this is just a double quote mark surrounded by two other double quote marks.\u201d Unfortunately, though, VBScript doesn\u2019t see it that way; instead, VBScript desperately tries to interpret that statement using its built-in parsing rules. One of those rules says that, for every opening double quote mark, there must be a corresponding ending quote; in other words, double quote marks must travel in pairs. When VBScript sees an odd number (three) of double quote marks it assumes that one of the pairs is missing a quote mark.<\/P>\n<P>Is that a problem? You bet it is: because of the syntax error the script won\u2019t even compile, let alone run.<\/P>\n<P>This \u2013 or some variation of it \u2013 is the situation JB has run into. So how do we work around the issue? There are actually a couple different ways to do that, but we chose this approach:<\/P><PRE class=\"codeSample\">strOldText = Chr(39)\nstrNewText = Chr(34)\n<\/PRE>\n<P>What we\u2019re doing here is using the <B>Chr<\/B> function to assign values to a couple of variables (strOldText and strNewText). If you provide Chr with an integer value (such as 39) it will report back the character that corresponds to that value. Guess what character has an ASCII value of 39? You got it: the single quote mark. As for ASCII value 34, that \u2013 well, needless to say, you\u2019re way ahead of us: yes, Chr(34) is the double quote mark.<\/P>\n<P>See what we\u2019re doing here? In the first line we\u2019ve assigned the single quote mark to the variable strOldText; this enables us to use a reference to the single quote mark without using the character itself. We then do the same thing with the double quote mark. Why? Because now we can call the Replace function and use variable names rather than problematic statements like &#8220;&#8221;&#8221;:<\/P><PRE class=\"codeSample\">strNewText = Replace(strText, strOldText, strNewText)\n<\/PRE>\n<P>This statement is syntactically correct. Equally important, it will replace all the single quote marks with double quote marks.<\/P>\n<TABLE class=\"dataTable\" id=\"EOG\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD class=\"\">\n<P class=\"lastInCell\"><B>Note<\/B>. So how did we know that Chr(39) was the single quote mark and Chr(34) was the double quote mark? Believe it or not that was something we just plain knew. (Sometimes the Scripting Guys <I>do<\/I> know what they\u2019re talking about &#8230; sort of) But you don\u2019t have to know that Chr(39) is the single quote mark; instead you can get ASCII values any time you need them simply by looking in the <A href=\"http:\/\/msdn2.microsoft.com\/en-us\/library\/6hy0yb50.aspx\" target=\"_blank\"><B>VBScript Language Reference<\/B><\/A>.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>The rest of the script practically writes itself. After reopening Test.txt (this time for writing) we call the <B>Write<\/B> method and replace the existing contents of the file with our newly-revised contents (the ones stored in the variable strNewText). We then close the text file and go back to planning tonight\u2019s dinner. Does garlic bread sound good to anyone else?<\/P>\n<P>Incidentally, when all is said and done our text file will look like this:<\/P><PRE class=\"codeSample\">&#8220;Ken Myer&#8221;,&#8221;Finance&#8221;,&#8221;Senior Analyst&#8221;\n&#8220;Pilar Ackerman&#8221;,&#8221;Human Resources&#8221;,&#8221;Manager&#8221;\n&#8220;Jonathan Haas&#8221;,&#8221;Transportation&#8221;,&#8221;Director&#8221;\n<\/PRE>\n<P>Which is exactly the way we want it to look.<\/P>\n<P>And now that today\u2019s column is done, and dinner is planned, it\u2019s time to head off to our first meeting, the one about budgets. Last year, for the first time ever, the Scripting Guys actually <I>got<\/I> a budget; we took that money and immediately spent the whole thing on <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/funzone\/bobbles.mspx\"><B>Dr. Scripto Bobblehead dolls<\/B><\/A>. That should make this year\u2019s budget meeting an interesting one, to say the least.<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! I saw your column on replacing text in a text file, and that\u2019s almost the solution I\u2019m looking for. However, the text I need to replace is the single quote mark, and I can\u2019t figure out how to do that. How do I replace single quote marks in a text file?&#8212; JB [&hellip;]<\/p>\n","protected":false},"author":595,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[3,4,14,5],"class_list":["post-64933","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-scripting-guy","tag-scripting-techniques","tag-text-files","tag-vbscript"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! I saw your column on replacing text in a text file, and that\u2019s almost the solution I\u2019m looking for. However, the text I need to replace is the single quote mark, and I can\u2019t figure out how to do that. How do I replace single quote marks in a text file?&#8212; JB [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/64933","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/595"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=64933"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/64933\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=64933"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=64933"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=64933"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}