我试图让所有子串与乘数匹配:
$list = '1,2,3,4';
preg_match_all('|\d+(,\d+)*|', $list, $matches);
print_r($matches);
此示例按预期返回[1]
中的最后一个匹配项:
Array
(
[0] => Array
(
[0] => 1,2,3,4
)
[1] => Array
(
[0] => ,4
)
)
但是,我想让(,\d+)
匹配所有字符串,以获得类似的内容:
Array
(
[0] => ,2
[1] => ,3
[2] => ,4
)
有没有办法使用preg_match_all()
等单一功能执行此操作?
答案 0 :(得分:8)
答案 1 :(得分:2)
使用lookbehind是一种完成工作的方法:
$list = '1,2,3,4';
preg_match_all('|(?<=\d),\d+|', $list, $matches);
print_r($matches);
所有,\d+
都在0组。
<强>输出:强>
Array
(
[0] => Array
(
[0] => ,2
[1] => ,3
[2] => ,4
)
)
答案 2 :(得分:1)
PHP(或更确切地说说PCRE)确实不存储重复捕获组的值以供以后访问(请参见PCRE docs):
如果捕获子模式重复匹配,则返回的是它匹配的字符串的最后一部分。
但是在大多数情况下,已知令牌\G
可以完成任务。 \G
1)匹配输入字符串的开头(如未设置\A
的情况下为^
或m
)或2)从上一个匹配结束处开始匹配。这样说,您必须像下面这样使用它:
preg_match_all('/^\d+|\G(?!^)(,?\d+)\K/', $list, $matches);
或者捕获组无关紧要:
preg_match_all('/\G,?\d+/', $list, $matches);
$matches
将通过其保存(请参见live demo):
Array
(
[0] => Array
(
[0] => 1
[1] => ,2
[2] => ,3
[3] => ,4
)
)
注意:与其他答案(例如\G
或后向解决方案或仅explode()
)相比,使用preg_match_all('/,?\d+/', ...)
的好处是您可以验证导出匹配项时,输入字符串只能同时处于所需格式^\d+(,\d+)*$
:
preg_match_all('/(?:^(?=\d+(?:,\d+)*$)|\G(?!^),)\d+/', $list, $matches);
答案 3 :(得分:0)
为什么不呢:
$ar = explode(',', $list);
print_r($ar);
答案 4 :(得分:0)
只有在模式中不使用要拆分的字符才能匹配时,拆分才是一个选项。 我的情况是,格式错误的逗号分隔行必须被解析为许多已知选项中的任何一个。
即。选项'1,2','2','2,3' 主题'1,2,3'。
分裂','将导致'1','2'和'3';只有一个('2')是有效匹配,这是因为分隔符也是选项的一部分。
天真的正则表达式会像'〜^(1,2 | 2 | 2,3)(?:,(1,2 | 2 | 2,3))* $〜我',但这会遇到同组捕获的问题。
我的“解决方案”是扩展正则表达式以匹配可能的最大匹配数: “〜^(1,2 | 2 | 2,3)(:,(1,2 | 2 | 2,3)?)?(?:,(1,2 | 2 | 2,3))?$〜一世' (如果有更多选项,只需重复'(?:,(1,2 | 2 | 2,3))?'位。 这会导致“未使用”匹配的空字符串结果。
这不是最干净的解决方案,但是当您必须处理格式错误的输入数据时,它才有效。
答案 5 :(得分:0)
来自http://www.php.net/manual/en/regexp.reference.repetition.php:
当重复捕获子模式时,捕获的值是与最终迭代匹配的子字符串。
也是类似的主题:
How to get all captures of subgroup matches with preg_match_all()?