PHP - REGEX - 匹配长度

时间:2011-05-11 16:41:45

标签: php regex

我有这个正则表达式:

^((?:(?:\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);

我的问题非常简单:为什么第二个字符串不匹配?

2 个答案:

答案 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可以匹配为ABCA / BCAB / CA / {{1} } / B。每个字符的排列数呈指数增长。通过使整个组可选(围绕整个事件的C),您进一步使问题复杂化。

答案 1 :(得分:0)

你只需要启用/multiline /m标志,然后它将匹配我在下面确认的两条线路。欢呼声

gskinner