note: I’m -not- trying to parse HTML with regex
I’m trying to replace any content wrapped in $ signs ($for example$) in a string. I’ve managed to come up with str.replace(/\$([^\$]*)\$/g), "hello $1!"), but I’m having issues with making sure I don’t replace such strings when they are wrapped in HTML tags.
Example string: $someone$, <a>$welcome$</a>, and $another$
Expression: /[^>]\$([^\$]*)\$[^<]/g
Expected output: hello someone!, <a>$welcome</a>, and hello another!
Actual output: $someonhello , !elcomhello , and !nother$
Test code: alert("$someone$, <a>$welcome$</a>, and $another$".replace(/[^>]\$([^\$]*)\$[^<]/g, "hello $1!"));
fiddle:
http://jsfiddle.net/WMWHZ/
Thanks!
Keep in mind that you have 6 ‘$’ in your test case. The problem here is that when you try to check if the previous character isn’t a ‘>’, the regexp moves forward and matches what’s between the 4th and the 5th dollar symbol, capturing
"</a>, and "and making a mess.Try this one:
Javascript doesn’t support lookbehinds in regular expressions, but it does support lookaheads (the
(?!<)part). To emulate lookbehinds, you correctly tried to put[^>]before the dollar, but then the character is matched so you have to catch it and put it again in the string.You just have to refine it a little, because if the ‘$’ is at the beginning of the string, the group isn’t captured.
Also, to avoid problems like the one above, you should check if there isn’t a ‘<‘ after the first dollar, so I put a
[^<]at the beginning of the capturing group. This also mean that it won’t catch empty strings between dollar symbols (as in ‘$$’), they must contain at least one character.This way, you have the expected result.