JavaScript否定前瞻性正则表达式产生错误结果

时间:2013-03-12 21:23:52

标签: javascript regex

假设以下网址:http://a2.mzstatic.com/us/ryoyo0/078/Purple100x100/v4/38/e3/b4/38e3b4a2-b422-8d1e-69f2-593fc035c9d4/mzl.vqhwzhhc.100x100-75.jpg

我们想用256x256替换最后一次出现的100x100。该URL应为:

http://a2.mzstatic.com/us/ryoyo0/078/Purple100x100/v4/38/e3/b4/38e3b4a2-b422-8d1e-69f2-593fc035c9d4/mzl.vqhwzhhc.256x256-75.jpg

这是我们的JavaScript替换方法:

replace( /100x100(?!100x100)/, '256x256' )

不幸的是,我们一直在替换第一次,而不是最后一次。

我们做错了什么?

谢谢!

4 个答案:

答案 0 :(得分:4)

试试这个:replace( /100x100(?!.*100x100)/, '256x256' )

在第一次出现和最后一次出现.*之间为其他字符添加100x100个帐户。

注意 - 虽然我的答案描述了你在模式中做错了什么以及如何解决它,但Billy Moon提供的答案可能是你似乎想要做的更好的模式。

答案 1 :(得分:3)

另一种方法......

replace( /(.*)100x100/, '$1256x256' )

通过...工作

  1. 使用100x100尽可能贪婪地将所有内容捕获到(.*)到第1组
  2. 匹配100x100
  3. 使用$1替换已捕获的组1,然后添加256x256代替未捕获的匹配
  4. NB 此方法仅适用于最后一场比赛(或者首先,如果您通过在?之后添加.*来使初始捕获变得非贪婪

    出于性能原因,为了与各种正则表达式实现的兼容性,通常避免使用环视断言通常是好的,并且我也相信可读​​性。

    编辑:测试脚本

    var url = "http://a2.mzstatic.com/us/ryoyo0/078/Purple100x100/v4/38/e3/b4/38e3b4a2-b422-8d1e-69f2-593fc035c9d4/mzl.vqhwzhhc.100x100-75.jpg"
    
    console.log(url.replace(/(.*)100x100/, '$1256x256'))
    
    // OUTPUT:
    // http://a2.mzstatic.com/us/ryoyo0/078/Purple100x100/v4/38/e3/b4/38e3b4a2-b422-8d1e-69f2-593fc035c9d4/mzl.vqhwzhhc.256x256-75.jpg
    

答案 2 :(得分:0)

你可以改变你的负向前瞻以寻找斜线。由于第二次出现以句号结束,而不是斜线,应该解决它。

/100x100(?!\/)/

答案 3 :(得分:0)

另一种方法,由于可能被误解的意图,它只替换出现在文件名部分中的100x100(字符串中没有出现/)。

replace(/100x100([^\/]*)$/, '256x256$1')

通过...工作

  1. 匹配100x100
  2. ...然后使用([^\/]*)
  3. 捕获到第1组,零个或多个,而不是正斜杠
  4. ...后跟字符串$
  5. 的结尾
  6. 替换为256x256和第一个捕获组$1
  7. 如果字符串中的最后一个/之后没有匹配,则不会进行替换。

    NB 我检查了这个答案的速度,我的另一个答案,以及@Daedalus的答案,虽然我通常希望避免断言加速正则表达式,在这种情况下,我有发现它们的速度完全相同,而且非常快,在我的电脑上每秒运行几十万次。