正则表达式只有“匹配”和“不匹配”两种状态吗?来看看第三种状态

@Ta 04-14 19:02 320点击

第三种状态——无限循环。
考虑以下JS代码:

  1. var url = 'http://www.example.com/dddp-web/pdf/download?request=6e7JGxxxxx4ILd-kExxxxxxxqJ4-CHLmqVnenXC692m74H38sdfdsazxcUmfcOH2fAfY1Vw__%5EDadIfJgiEf'
  2. var reg = /^(https?:\/\/)(([A-Za-z0-9-~]+).)+([A-Za-z0-9-~\\\/])+$/i
  3. console.log(reg.test(url))

初看上去,结果应该是false,因为url中包含reg中不存在的字符? _ %等。
不过实际运行效果如何呢?

我们通过 https://regex101.com/ 网站来模拟一下这个正则表达式的匹配流程:

这个问题是怎么造成的呢?其实就是因为
var reg = /^(https?:\/\/)(([A-Za-z0-9-~]+).)+([A-Za-z0-9-~\\/])+$/i

没错就是因为这个点。这里本来是想匹配域名中的点本身,但是由于忘记加\,变成了匹配任意字符。于是([A-Za-z0-9-~]+).便可以匹配到download?request=6e7JGxxxxx4ILd-kExxxxxxxqJ4-CHLmqVnenXC692m74H38sdfdsazxcUmfcOH2fAfY1Vw_等一系列片段,但由于后面的([A-Za-z0-9-~\\\/])+$始终与剩余部分不匹配,就发生了一系列“完全停不下来”的返回重新匹配,也称为“灾难性回溯”。

如果改成这样就完全没问题了:

  1. var url = 'http://www.example.com/dddp-web/pdf/download?request=6e7JGxxxxx4ILd-kExxxxxxxqJ4-CHLmqVnenXC692m74H38sdfdsazxcUmfcOH2fAfY1Vw__%5EDadIfJgiEf'
  2. var reg = /^(https?:\/\/)(([A-Za-z0-9-~]+)\.)+([A-Za-z0-9-~\\\/])+$/i
  3. console.log(reg.test(url))


备注:PHP不会发生无限循环,可以返回false,是因为pcre.backtrack_limit参数限制了可回溯的次数。当回溯次数超过限制时就会放弃匹配并返回false。


创意来源:https://zhuanlan.zhihu.com/p/38278481

回复列表(13)
  • 1
    @Ta / 04-14 18:46
    1
  • 2
    @Ta / 04-14 22:17

    三个滑稽币暖贴
  • 3
    @Ta / 04-14 22:26
    很少用,通常我都是复制别人提供的常用规则
  • 4
    yun
    @Ta / 04-15 00:35
    涨知识了
  • 5
    @Ta / 04-15 09:53
    还有这种操作,学习了
  • 6
    @Ta / 04-15 10:11

    问问[A-Za-z0-9-~]中的波浪号有什么作用,或者说0-9-~有什么作用呢?

  • 7
    @Ta / 04-15 10:16

    new reg = /(.*)/gm 不也是最简单的死循环吗

  • 8
    @Ta / 04-15 11:26
    所以php是世界上最好的语言
    这是一条小尾巴,你们不必羡慕!
  • 9
    @Ta / 04-15 18:40

    @水木易安.*会一次性匹配掉所有字符,然后直接就返回true了啊。

    要构造一个灾难性回溯的话,应该是前半部分可以与字符串的任何前缀匹配,但是后半部分与字符串的任何后缀都不匹配。这样正则表达式引擎就会不断调整前半部分和后半部分的长度进行尝试。

  • 10
    @Ta / 04-15 18:42

    @Curtion,最后的-和~都表示这两个字符本身。
    [A-Za-z0-9-~]表示允许出现字母、数字、减号与波浪线。

  • 11
    @Ta / 04-15 21:20

    @老虎会游泳,行吧,我翻了一下MDN没找到我还以为是新东西呢..

  • 12
    @Ta / 04-16 02:08
    看不懂
  • 13
    @Ta / 04-17 22:49
    @老虎会游泳,有道理 
添加新回复
回复需要登录

[聊天-垃圾葫芦林] 老虎会游泳:@Op112_Com,你的举报单位既没有图中背景的版权,也没有图中前景的版权。我倒是愿意他们起诉我,…