所以我想出了以下正则表达式:
([^\s\\]+(?:\\.[^\s\\]*)*)(?:.*?)(\S+\.php\b)
测试链接:https://regex101.com/r/NV6Bk4/4
它与命令行的二进制名称和脚本名称匹配。示例:
php --strict myscript.php --arg=value
匹配组(1)和组(2)中的php
和myscript.php
。
问题是中间的这一部分:(?:.*?)
,它导致组合爆炸,从而减慢了大输入量的正则表达式。有没有一种方法可以对此进行优化?既然没有模式,我什么都想不起来。
为了澄清,我要匹配的规则是: 将任何路径匹配到命令,可能包含转义的空格。忽略其后的所有参数。匹配以.php结尾的文件,忽略其后的所有内容。该命令应该在组(1)中,文件名应该在组(2)中。
答案 0 :(得分:1)
您可以在Matcher#matches()
中使用以下“修复程序”:
([^\s\\]*+(?:\\.[^\s\\]*)*).*?(\S+\.php\b).*
在Java中
String regex = "([^\\s\\\\]*+(?:\\\\.[^\\s\\\\]*)*).*?(\\S+\\.php\\b).*";
请参见regex demo。请注意,字符类外部的文字.
必须转义。如果字符串可能有换行符,请使用Pattern.DOTALL
编译模式。
如您所见,.*?
部分匹配任何字符,并且(?:\\.[^\s\\]*)*
可以匹配任何0个或更多字符(因此,它是可选的),以及{{左侧的1}}是.*?
,可以与[^\s\\]+
匹配相同的字符。这意味着,正则表达式引擎可能会回溯到第一个子模式,从而创建了许多匹配字符串的方法,通常称为灾难性回溯。
如果您不允许使用.*?
所有格量词回溯到第一个否定字符类,它将已经更加可靠了。
在末尾添加*+
,使其与.*
一起使用,因为此方法需要完整的字符串匹配。