views:

67

answers:

4

I want to escape all quotes that comes only after the text H1:

For instance, :

H1: "text here"

should become:

H1: "text here"

This would be easy with lookbehind, but that's not in JS.

something I tried:

.replace(/H1:(.*)(")(.*)/ig, "H1:$1"$2")

Also it should work on other similar text like:

H1: ""text here""
H1: "text "here""
H1: ""text here"
+1  A: 

Here's one approach:

function encodeQuotesOccuringAfter(string, substring) {
    if(string.indexOf(substring) == -1) {
        return string;
    }

    var all = string.split(substring);
    var encoded = [all.shift(), all.join(substring).replace(/"/g, """)];

    return encoded.join(substring)
}

This second one is a bit wasteful, but you could move this into a function, and compute startAt only once. Idea is to look for all quotes, and only change the ones that have "H1:" appear before them.

str.replace(/"/g, function(match, offset, string) {
    var startAt = string.indexOf("H1:");
    if(startAt != -1 && offset > startAt) {
        return """;
    }
    else {
        return '"';
    }
});

Using our domain knowledge that H1: does not contain quotes, we simply do a replace on the entire string.

str.replace(/"/g, """);
Anurag
But this will also change `H2: "text here"` or `completely "random" quote marks "here"`, which we may not want. Mark specifically says, that there are some quote marks that should not be changed.
Peter Ajtai
@Peter - thanks for pointing that out. Updating answer.
Anurag
For the second one, this doesn't check whether or not the `H1:` is on the same line is it.
Mark
@Mark - I wasn't aware that you conceptually have lines of text rather than a string. None of my answers consider lines in the text.
Anurag
A: 

try this:

.replace(/H1:(.*?)(")(.*?)/ig, "H1:$1"$3")

*? Matches 0 or more of the preceeding token. This is a lazy match, and will match as few characters as possible before satisfying the next token.

This is the web site that I use for testing regular expressions: http://gskinner.com/RegExr/

davidgarza
Doesn't work (replaces only one quote) -- better check your solution before posting.
Amnon
Thanks for the site. Looks useful. But yes, this matches only 1 quote.
Mark
A: 

First I split the string into lines. Then I only do the text replacement on the correct lines, and while I do the text replacement I concatenate all the lines back together:

<script type="text/javascript">
  // Create a test string.
var string='H1: "text here" \nH1: test "here" \nH2: not "this" one';
  // Split the string into lines
array = string.split('\n');
  // Iterate through each line, doing the replacements and 
  // concatenating everything back together
var newString = "";
for(var i = 0; i < array.length; i++) {
      // only do replacement if line starts H1
      // /m activates multiline mode so that ^ and $ are start & end of each line
    if (array[i].match(/^H1:/m) ) {
          // Change the line and concatenate
          // I used &quote; instead of &quote; so that the changes are
          // visible with document.write
        newString += array[i].replace(/"/g, '&quote;') + '\n';    
    } else {
          // only concatenate
        newString += array[i] + '\n';
    }
}
document.write(newString);
</script>
Peter Ajtai
Can you show me how to rejoin the replaced arrays back into the string?
Mark
@Mark - I edited the code so that it produces one modified string called newString that contains all the original lines, but with the H1 line modified.
Peter Ajtai
+1  A: 

Split the text into lines, then, for every line that begins with "H1", simply do a replace.

Just be aware that the &quot; character may be replaced by the JavaScript engine with a real quote if it's embedded inside HTML. (Edit: it got replaced when I tried to write it directly in this answer).

Amnon