Javascript Jquery.replace浏览器
这行代码(我相信)查找以foo开头、以bar结尾的子字符串,该子字符串包含任何内容,包括换行符,并将其从字符串中删除Javascript Jquery.replace浏览器,javascript,jquery,regex,string,replace,Javascript,Jquery,Regex,String,Replace,这行代码(我相信)查找以foo开头、以bar结尾的子字符串,该子字符串包含任何内容,包括换行符,并将其从字符串中删除 zip = string.replace(/foo(.|\s)*bar/, ''); 出于某种原因,当我把一个非常大的字符串放在这段代码中,其中很大一部分不在foo和bar之间时,它会崩溃。Chrome不显示任何错误消息,控制台也不显示,但选项卡冻结,除了关闭外,拒绝执行任何操作 对于外部相对较小的内容,这不会崩溃,而对于foo和bar内部的大量内容,它不会崩溃。这并不是因为字
zip = string.replace(/foo(.|\s)*bar/, '');
出于某种原因,当我把一个非常大的字符串放在这段代码中,其中很大一部分不在foo和bar之间时,它会崩溃。Chrome不显示任何错误消息,控制台也不显示,但选项卡冻结,除了关闭外,拒绝执行任何操作
对于外部相对较小的内容,这不会崩溃,而对于foo和bar内部的大量内容,它不会崩溃。这并不是因为字符串太大,JS对它的字符串没有限制,其他.replace函数也使用相同大小的字符串。它可能是一个写得很糟糕的正则表达式还是什么?语法(.|\s)*
有点奇怪
它基本上是(捕获除新行或捕获空白以外的任何内容){根据需要多次}
,但是JavaScript没有一种模式。匹配新行字符
请尝试使用/foo([\s\s]*)条/
。[\s\s]
字符类匹配的字符可以是空白字符(包括换行字符),也可以是非空白字符。由于所有字符都是空白或非空白字符,因此此字符类匹配任何字符。看
崩溃的原因很可能是所建议的“回溯地狱”(.|\s)*
的语法有点奇怪
它基本上是(捕获除新行或捕获空白以外的任何内容){根据需要多次}
,但是JavaScript没有一种模式。匹配新行字符
请尝试使用/foo([\s\s]*)条/
。[\s\s]
字符类匹配的字符可以是空白字符(包括换行字符),也可以是非空白字符。由于所有字符都是空白或非空白字符,因此此字符类匹配任何字符。看
崩溃的原因很可能是所建议的“回溯地狱”,浏览器使用regex
/foo(.|\s)*bar/
崩溃,而不是pete所建议的/foo[\s\s]*bar/
由于回溯地狱而崩溃
一个(未优化的)NFA正则表达式引擎将尝试第一个分支,如果匹配失败,它将返回到第二个分支。更好的引擎可以分析语法,并将
和\s
组合成一个字符类,这样就不会浪费时间回溯
让我们考虑这个输入:
foo notba other
对于正则表达式/foo(.|\s)*bar/
,由于空格(ASCII 32)可以同时匹配
和\s
,在
分支匹配失败后,它将尝试\s
分支:
foo notba other
^^^^^^^^^^^ ^^^^^
空格字符数是正则表达式引擎探索的二叉树的级别数。如果字符串包含foo
,但不包含bar
,则时间复杂度会随着空白字符的数量呈指数级增加
以pete的修改为例,
/foo[\s\s]*bar/
,没有分支,因为所有内容都已由character类检查过,因此当我们在失败时回溯时,我们没有任何未探索的分支,并且会很快返回失败。浏览器会使用regex/foo(.|\s)*/bar/
,而不是/foo[\s\s]*bar/
如pete所建议,由于回溯地狱
一个(未优化的)NFA正则表达式引擎将尝试第一个分支,如果匹配失败,它将返回到第二个分支。更好的引擎可以分析语法,并将
和\s
组合成一个字符类,这样就不会浪费时间回溯
让我们考虑这个输入:
foo notba other
对于正则表达式/foo(.|\s)*bar/
,由于空格(ASCII 32)可以同时匹配
和\s
,在
分支匹配失败后,它将尝试\s
分支:
foo notba other
^^^^^^^^^^^ ^^^^^
空格字符数是正则表达式引擎探索的二叉树的级别数。如果字符串包含foo
,但不包含bar
,则时间复杂度会随着空白字符的数量呈指数级增加
考虑pete的修改
/foo[\s\s]*bar/
,没有分支,因为所有内容都已由character类检查,因此当我们在失败时回溯时,我们没有任何未经探索的分支,并且会很快返回失败。好吧,它的语法有点奇怪(.|\s)*
是(捕获除新行以外的任何内容或捕获空白){根据需要多次}
,但JavaScript没有模式使
匹配新行
字符。。。你试过/foo[\s\s]*bar/
吗?看起来很管用-\u-我觉得我的语法很奇怪,但我不知道该怎么做。这里的问题是*
太贪婪了。如果你不想让“bar”介于“foo”和“bar”之间,那么你应该使用非贪婪量词*?
,而不是*
@Pointy,这是有意义的,但是为什么它在正则表达式外使用相对较少的字符串?为什么@pete的答案会修复它,因为它仍然贪婪?好吧,它的语法有点奇怪(.|\s)*
是(捕获除新行以外的任何内容或捕获空白){根据需要多次}
,但JavaScript没有模式使
匹配新行
字符。。。你试过/foo[\s\s]*bar/
吗?看起来很管用-\u-我觉得我的语法很奇怪,但我不知道该怎么做。这里的问题是*
太贪婪了。如果你不想让“酒吧”介于“foo”和“bar”之间,那么你应该使用非gre