我需要以字符串形式获取所有匹配项,当单词以@
开头,然后只包含alnym 0-9a-z
个字符。例如,从这个字符串@ww@ee x@@vx @ss @aa assadd @sfsd
我需要得到这些:
@ss
@aa
@sfsd
我在尝试:
$str = "@ww@ee x@@vx @ss @aa assadd @sfsd";
preg_match_all("#(^|\s)\@([0-9a-z]+)(\s+|$)#ui", $str, $matches);
var_dump( $matches );
但这只给@ss
@sfsd
并跳过@aa
。
这是什么样的模式?
答案 0 :(得分:4)
您可以使用以下正则表达式
'~\B(?<!@)@([0-9a-z]+)(?:\s|$)~iu'
请参阅regex demo,此处是IDEONE demo:
$re = '~\B(?<!@)@([0-9a-z]+)(?:\s|$)~ui';
$str = "@ww@ee x@@vx @ss @aa assadd @sfsd";
preg_match_all($re, $str, $matches);
print_r($matches);
正则表达式的解释:
\B
- 匹配非字边界位置(即,^
和\w
,\w
和$
之间的所有位置,{{1 }}和\W
,\w
和\w
)\W)
- 如果当前位置之前有(?<!@)
@
- @
符号(无需转义)@
- 第1组(由于([0-9a-z]+)
未转义,因此它们捕获子模式并将其存储在特殊的内存插槽中)(...)
- 与空白((?:\s|$)
)或\s
匹配的非捕获组(仅用于组合备选方案)。 $
修饰符允许正确处理Unicode字符串(~ui
)并使模式不区分大小写(u
)。
请注意,i
强制在\B
之前显示非字字符。但是,如果另一个@
位于@
之前,则您不希望匹配。因此,我们必须使用负面的后置@wwww
来进一步限制匹配。