1

wish to escape all occurrences of "." and ":" within square brackets

[ab:1.2:ef]='12.3' => [ab\:1\.2\:ef]='12.3'

tried various permutations on replace, eg,

str.replace( /(\[.*)(\.|:)(.*\])/g, '\1\\\2\3' );

but no joy.


Both answers correct and more.

The first, a pure pattern match, does the job and is very succinct. In my opinion it answers the stated question better.

The second, calling replace with a function arg, is a wee bit more robust and offers considerably more flexibility. In my code using this approach because it handles a couple of special cases easily.

2 Answers 2

2

Assuming that the brackets are always correctly balanced (even within strings or comments) and can never be nested or escaped, you can solve this in a single regex using lookahead assertions:

result = subject.replace(/([:.])(?=[^[\]]*\])/g, "\\$1");

As a commented regex:

([:.])    # Match and remember a dot/colon,
(?=       # only if it is followed by:
 [^[\]]*  # any number of characters excluding brackets,
 \]       # followed by a closing bracket.
)         # End of lookahead assertion.

The lookahead ensures that the next bracket after the dot/colon we're looking at is a closing bracket.

Sign up to request clarification or add additional context in comments.

3 Comments

great explanation. took me by surprise that you're not worrying about the leading bracket (since it has to be there) - makes the matching less complex.
This doesn't require both opening and closing brace. Thus, it doesn't work for: [ab:1.2:ef]='12.3]' or ab:1.2:ef]='12.3'.
Right, that's why I wrote that the brackets must be correctly balanced (JavaScript doesn't support lookbehind assertions). I should add that this also concerns brackets inside strings, comments etc.
1

I only know how to do it with a replace function:

var test = "[ab:1.2:ef]='12.3'";

var out = test.replace(/\[.*?\]/g, function(str) {
    return(str.replace(/\.|:/g, "\\$&"));
});

// out is [ab\:1\.2\:ef]='12.3'

See it in action here: http://jsfiddle.net/jfriend00/ZHVjW/

5 Comments

wow! have never seen a function used as the argument in replace - very cool. much more elegant than the match loop was using before. thanks!
Concerning your comment to my answer, your regex will also have problems with unbalanced brackets in strings like [ab:1.2] = '[12.3'; [cd:3.4] = '34.5]'. As soon as delimiters are unbalanced and/or inside strings/comments, regexes start to fail, and you need a parser for this kind of job.
Yes, fine line between getting job done and bring out the big iron. That said, do you know of a utility that will transform a (somewhat) arbitrary string into polish-type tree structure?
@TimPietzcker - the example you point out is nested brackets. The OP didn't specify that nested brackets were a requirement. The solution for nested would be much more complicated (probably not just a regex problem) with either approach. I just thought it odd that your solution doesn't require an opeing bracket of any kind. If the OP is OK with that, no big deal.
Which nested brackets? Those would have been an additional problem (for all of our regexes); here there's just brackets inside strings. The problem would have remained identical with [ab:1.2] = '[12.3'; [cd:3.4] = '34.5'.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.