我有这个正则表达式:
^((?:(?:\s*[a-zA-Z0-9]+)*)?)\s*function\s+([_a-zA-Z0-9]+)\s+\(\s*(.*)\s*\)\s*
匹配此字符串:
public function private ($var,Type $typed, $optional = 'option');
它有效,但在匹配这个时:
public function privateX ($var,Type $typed, $optional = 'option');
失败了。
我注意到当函数名称的长度超过6个字符时,它就不再匹配了。
以下是完整代码:
$strA = 'public function 6Chars ($var,Type $typed, $optional = "option");';
$strB = 'public function MoreThan7 ($var,Type $typed, $optional = "option");';
preg_match('!^((?:(?:\s*[a-zA-Z0-9]+)*)?)\s*function\s+([_a-zA-Z0-9]+)\s+\(\s*(.*)\s*\)\s*!',$strA,$mA);
preg_match('!^((?:(?:\s*[a-zA-Z0-9]+)*)?)\s*function\s+([_a-zA-Z0-9]+)\s+\(\s*(.*)\s*\)\s*!',$strB,$mB);
print_r($mA);
print_r($mB);
我的问题非常简单:为什么第二个字符串不匹配?
答案 0 :(得分:3)
我无法在RegexBuddy中重现这一点;两个声明都匹配。但是,正则表达式引擎所需的步骤与每个字符的匹配加倍。函数名称为6个字符,需要大约100.000步的正则表达式引擎,7个字符200.000步,8个字符400.000步等。
也许正则表达式引擎会在经过一定步骤后放弃?
占有量词(++
)通过减少正则表达式引擎必须经历的可能排列所需的步数大幅减少 - 无论函数名称的长度如何,都会有50步。
!^((?:(?:\s*[a-zA-Z0-9]++)*)?)\s*function\s+([_a-zA-Z0-9]+)\s+\(\s*(.*)\s*\)\s*!
您在正则表达式中看到的灾难性回溯的原因是:
(?:(?:\s*[a-zA-Z0-9]+)*)
您正在嵌套量词,并且您已将空格设为可选。因此,ABC
可以匹配为ABC
,A
/ BC
,AB
/ C
或A
/ {{1} } / B
。每个字符的排列数呈指数增长。通过使整个组可选(围绕整个事件的C
),您进一步使问题复杂化。
答案 1 :(得分:0)
你只需要启用/multiline /m
标志,然后它将匹配我在下面确认的两条线路。欢呼声