Php正则表达式:匹配重复模式

时间:2009-10-31 11:44:46

标签: php regex

我想匹配下面的字符串。

abc|q:1,f:2
cba|q:1,f:awd2,t:3awd,h:gr

我正在使用php,并使用此表达式尝试了preg_matchpreg_match_all

/^([a-z]+)\|([a-z]+:[a-z0-9]+,?)+$/iU

这只返回管道前的第一部分,一个a:1。我做错了什么,它为什么会这样,我怎么能让它运作?

3 个答案:

答案 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);