这是我的测试代码:
$test = '@12345 abc @12 @abd engng@geneng';
preg_match_all('/(^|\s)@([^@ ]+)/', $test, $matches);
print_r($matches);
输出$matches
:
Array ( [0] => Array ( [0] => @12345 [1] => @12 [2] => @abd ) [1] => Array ( [0] => [1] => [2] => ) [2] => Array ( [0] => 12345 [1] => 12 [2] => abd ) )
我的问题是为什么它有一个空行?
[1] => Array ( [0] => [1] => [2] => )
如果我在(^|\s)
中乘坐regex
,第二行将会消失。但是,我无法阻止匹配@geneng
。
任何答案都将不胜感激。
答案 0 :(得分:2)
正则表达式的问题在于它匹配@
,即使它前面有空格。因为\s
将匹配空格,所以它将被捕获到$matches
数组中。您可以使用lookarounds解决此问题。在这种情况下,它可以通过积极的观察来解决:
preg_match_all('/(?<=^|\s)@([^@ ]+)/', $test, $matches);
这将匹配@
仅之后的部分(如果它前面有空格或行首锚点)。重要的是要注意,lookarounds实际上并不消耗字符。他们只断言给定的正则表达式是在其后面或之前。
答案 1 :(得分:1)
这是因为要测试(^|\s)
的内存捕获:
preg_match_all('/(^|\s)@([^@ ]+)/', $test, $matches);
^^^^^^
它被捕获为内存位置#1,所以为了避免你可以简单地使用非捕获括号:
preg_match_all('/(?:^|\s)@([^@ ]+)/', $test, $matches);
^^
答案 2 :(得分:0)
preg_match_all默认使用PREG_PATTERN_ORDER标志。这意味着您将获得:
$matches[0] -> all substrings that matches the whole pattern
$matches[1] -> all capture groups 1
$matches[2] -> all capture groups 2
etc.
您可以使用PREG_SET_ORDER标志更改此行为:
$matches[0] -> array with the whole pattern and the capture groups for the first result
$matches[1] -> same for the second result
$matches[2] -> etc.
在您的代码中(默认为PREG_PATTERN_ORDER),您只获得$ matches [1],只包含空或空白项目,因为它是捕获组1的内容(^|\s)
答案 3 :(得分:0)
有两组括号,这就是为什么你得到一个空行。 PHP认为,你想要在字符串中有2组匹配。删除其中一个将删除一个阵列。
仅供参考:在这种情况下,您不能使用[^ | \ s]而不是(^ | \ s)。因为PHP会想,你要排除空格。