Javascript正则表达式Lookbehind Failing

问题描述:

我希望这会有一个非常快速和简单的答案。我使用regular-expressions.info来帮助我获得正确的正则表达式,以将URL编码的ISO-8859-1英镑符号(“%A3”)转换为URL编码的UTF-8英镑符号(“%C2%A3”) 。Javascript正则表达式Lookbehind Failing

换句话说,我只想将%A3换成%C2%A3,当%A3尚未加上%C2前缀时。

所以我还以为下面将工作:

Regular Expression: (?!(\%C2))\%A3 
Replace With:  %C2%A3 

但事实并非如此,我想不通为什么!

我认为我的语法有点不对,但我弄不明白!有任何想法吗?

仅供参考 - 我知道以下内容会起作用(并且在此期间用它作为解决方法),但真的很想理解为什么前者不起作用。

Regular Expression: ([^\%C2])\%A3 
Replace With:  $1%C2%A3 

TIA!

+0

我认为你需要一个编码转换器将ISO 8859-1转换为UTF-8。 – Gumbo 2009-09-07 16:56:09

为什么不把((%C2)?%A3)替换成%C2%A3,使前缀成为匹配的可选部分?这意味着即使它已经是正确的,你也可以用自己“替换”文本,但是我没有预见到性能问题。

+0

听起来不错 - 不知道为什么我没有想到 - 谢谢! :)不接受它作为答案,因为它本质上是另一种解决方法(问题的关键是要找出为什么我的后视不工作),但谢谢! – FrostbiteXIII 2009-09-08 09:14:27

+0

忽略 - 接受的答案 - 非常感谢! :) – FrostbiteXIII 2009-09-08 09:29:50

+0

非常好,+1。你可以使用'(?:(?:%C2)?%A3)',因为在这种情况下反向引用并不是真的需要。 – Tomalak 2009-09-08 09:38:50

不幸的是,(?!)语法是负向预测。就我所知,JavaScript不支持负向后视。

你可以做的是继续进行替换,并以%C2%C2%A3字符串结束,但这些可以很容易地在第二次转换为期望的%C2%A3。

+0

我已经问了两次或三次在ECMAScript,mozilla.dev.tech.js-engine新闻组中添加了后视操作符,并且没有回复。随意添加您的声音。 http://groups.google.com/group/mozilla.dev.tech.js-engine/browse_thread/thread/5d8e24ca46aa72f1?hl=zh-CN# – 2009-09-07 16:21:36

+0

感谢您的快速回答。听起来很愚蠢,但我发现很难理解前瞻和后脑之间的主要区别 - 在我看来(我知道我错了,否则就不会有两个不同的名字!),它只是做一个搜索一些字符,但不使用这些替换? 并感谢您的建议,但我认为我的解决方法稍微整洁。 :) – FrostbiteXIII 2009-09-07 16:23:19

+0

这样想吧....正则表达式通常通过跟踪您当前在字符串中的位置来工作。这可能是以找出你曾经去过的地方(向后看)和你要去的地方(向前看)为代价。由于追踪您当前的位置,因此可能存在实现后视的实施困难。 – 2009-09-07 16:26:21

您可以取代

(^.?.?|(?!%C2)...)%A3 

$1%C2%A3 
+0

这在某些情况下似乎太匹配了。尝试将其与文本“ladskfjdkfj%A3”进行匹配,看起来kfj%A3匹配。 – 2009-09-07 16:29:54

+0

...直到我删除了省略号,但即使如此,字符串“ladskfjd%C2%A3”也匹配,尽管它不应该... JavaScript并没有让这种简单! – 2009-09-07 16:31:02

+0

@Tomalak:+1这就是我会写的。 – Gumbo 2009-09-07 16:33:10

我会建议你使用the functional form of Javascript String.replace(请参见 “指定函数作为参数”)。这使您可以将任意逻辑(包括必要时的状态)放入正则表达式匹配会话中。对于你的情况,我会使用一个更简单的正则表达式来匹配你想要的超集,然后在函数调用中你可以测试它是否符合你的准确条件,如果不符合,那么只是按照原样返回匹配的字符串。

这种方法唯一的问题是如果你有重叠的潜在匹配,你有可能错过第二个匹配,因为没有办法返回一个值来告诉replace()方法,它不是真的毕竟是一场比赛。