2012-05-24 53 views
3

注:我-not-试图解析HTML与正则表达式

我试图取代包裹在$迹象任何内容($例如$)在一个字符串中。我设法想出了str.replace(/\$([^\$]*)\$/g), "hello $1!"),但我在确保在用HTML标记包装时不会替换这些字符串时遇到问题。

例字符串:$someone$, <a>$welcome$</a>, and $another$

表达:/[^>]\$([^\$]*)\$[^<]/g

预期输出:hello someone!, <a>$welcome</a>, and hello another!

实际输出:$someonhello , !elcomhello , and !nother$

测试代码:alert("$someone$, <a>$welcome$</a>, and $another$".replace(/[^>]\$([^\$]*)\$[^<]/g, "hello $1!"));

拨弄: http://jsfiddle.net/WMWHZ/

谢谢!

+1

我认为我们需要退后一步。你如何得到你正在解析的文本?你试图解决什么样的问题? – mkoryak

+0

当你谈论HTML标签中包含的内容时,你实际上正在谈论解析HTML。因为如果不解析,你会如何决定HTML标记中包含的内容? – Gumbo

+0

...并不会*每个*文本都包裹在一些HTML标签中,实际上? – Joey

回答

4

请记住,您的测试用例中有6个'$'。这里的问题是,当你尝试检查,如果前一个字符是不是一个“>”,正则表达式向前移动并匹配有什么和美元符号之间,捕捉"</a>, and ",使一个烂摊子。

试试这个:

$('div').text(test.replace(/(^|[^>])\$([^<][^\$]*)\$(?!<)/g, "$1hello $2!"))​ 

JavaScript不支持lookbehinds正则表达式,但它支持向前看符号(在(?!<)部分)。为了模拟向后看,你正确地试图把[^>]放在美元前面,但是这个字符是匹配的,所以你必须抓住它,并把它放在字符串中。

您只需稍微改进一下,因为如果'$'位于字符串的开头,则不会捕获该组。

此外,为避免类似上面的问题,您应该检查是否有不“<” 第一后美元,所以我把[^<]在捕获组的开始。这也意味着它不会捕获美元符号之间的空字符串(如'$$'),它们必须至少包含一个字符。

这样,您就得到了预期的结果。

+0

你应该更新小提琴并发布 – mkoryak

+0

好,不客气:http://jsfiddle.net/WMWHZ/1/ – MaxArt

+0

'(^ | [^>])'组应该是非捕获'(? :^ | [^>])'或者你可以捕获不需要的空间。 –