我想匹配下面的字符串。
abc|q:1,f:2
cba|q:1,f:awd2,t:3awd,h:gr
我正在使用php,并使用此表达式尝试了preg_match
和preg_match_all
。
/^([a-z]+)\|([a-z]+:[a-z0-9]+,?)+$/iU
这只返回管道前的第一部分,一个a:1。我做错了什么,它为什么会这样,我怎么能让它运作?
答案 0 :(得分:3)
/^([a-z]+)\|((?:[a-z]+:[a-z0-9]+,?)+)$/iU
会抓住:
'+'quantifier的贪婪本质使你的捕获组([az] +:[a-z0-9] +,?)仅捕获与此正则表达式匹配的最后一组字符。
/(?ms)^((?:[a-z]+)\|(?:[a-z]+:[a-z0-9]+,?)+)$/iU
将捕获所有行。
请注意“?:
”以避免creating any capturing group。
答案 1 :(得分:0)
我刚试过:
<?php
$string = 'cba|q:1,f:awd2,t:3awd,h:gr';
$subpat = '[a-z]+:[a-z0-9]+';
$pat = "/^([a-z]+)\|($subpat(?:,$subpat)+)$/i";
preg_match( $pat, $string, $matches );
print_r( $matches );
?>
产生
Array
(
[0] => cba|q:1,f:awd2,t:3awd,h:gr
[1] => cba
[2] => q:1,f:awd2,t:3awd,h:gr
)
此时,您在matches[1]
中的垂直条之前有部分,matches[2]
中的其余部分。重复$subpat
是为了确保字符串可以用逗号正确分隔。之后,在matches[2]
上应用explode。
答案 2 :(得分:0)
$string = 'cba|q:1,f:awd2,t:3awd,h:gr';
$re = '~(?: ^(\w+)\| ) | (?: (\w+) : (\w+) (?:,|$) )~x';
preg_match_all($re, $string, $m, PREG_SET_ORDER);
var_dump($m);
这将匹配管道(“前导”)之前的部分和所有键值对。 “引导”将位于$m[0][1]
中,键值将位于$m[1..x][2] and [3]
中。添加一些简单的后处理以将其转换为可用的形式,例如:
$lead = $m[0][1];
foreach(array_slice($m, 1) as $p)
$data[$p[2]] = $p[3];
var_dump($lead, $data);