正则表达式,用于解析用双括号括起来的管道分隔数据

时间:2009-08-25 14:15:26

标签: php regex preg-match

我正在尝试匹配这样的字符串:

{{name|arg1|arg2|...|argX}}

带有正则表达式

我正在使用preg_match

/{{(\w+)\|(\w+)(?:\|(.+))*}}/

但是每当我使用两个以上的args时,我就会得到类似的东西

Array
(
    [0] => {{name|arg1|arg2|arg3|arg4}}
    [1] => name
    [2] => arg1
    [3] => arg2|arg3|arg4
)

前两项不能包含空格,其余的可以。 也许我在这方面工作太久了,但我找不到错误 - 任何帮助都会非常感激。

谢谢Jan

5 个答案:

答案 0 :(得分:4)

不要将正则表达式用于这些简单的任务。你真正需要的是:

$inner = substr($string, 2, -2);
$parts = explode('|', $inner);

# And if you want to make sure the string has opening/closing braces:
$length = strlen($string);
assert($inner[0] === '{');
assert($inner[1] === '{');
assert($inner[$length - 1] === '}');
assert($inner[$length - 2] === '}');

答案 1 :(得分:3)

问题在于:\ |(。+)

默认情况下,正则表达式匹配尽可能多的字符。自从。是任何字符,|的其他实例我也很乐意相配,这不是你想要的。

为防止这种情况,您应该排除|从表达式,说“匹配除了|之外的任何东西”,得到\ |([^ \ |] +)。

答案 2 :(得分:0)

适用于从1到 N 参数的任何地方

<?php

$pattern = "/^\{\{([a-z]+)(?:\}\}$|(?:\|([a-z]+))(?:\|([a-z ]+))*\}\}$)/i";

$tests = array(
    "{{name}}"                          // should pass
  , "{{name|argOne}}"                   // should pass
  , "{{name|argOne|arg Two}}"           // should pass
  , "{{name|argOne|arg Two|arg Three}}" // should pass
  , "{{na me}}"                         // should fail
  , "{{name|arg One}}"                  // should fail
  , "{{name|arg One|arg Two}}"          // should fail
  , "{{name|argOne|arg Two|arg3}}"      // should fail
  );

foreach ( $tests as $test )
{
  if ( preg_match( $pattern, $test, $matches ) )
  {
    echo $test, ': Matched!<pre>', print_r( $matches, 1 ), '</pre>';
  } else {
    echo $test, ': Did not match =(<br>';
  }
}

答案 3 :(得分:0)

当然你会得到这样的东西:)正则表达式中没有办法返回匹配的动态计数 - 在你的情况下是参数。

看看你想做什么,你应该跟上当前的正则表达式,然后用'|'爆炸额外的args并将它们添加到args数组中。

答案 4 :(得分:0)

确实,这是来自PCRE手册:

  

当捕获子模式是   重复,捕获的值是   与最终匹配的子字符串   迭代。例如,之后   (tweedle [dume] {3} \ s *)+已匹配   “tweedledum tweedledee”的价值   捕获的子串是   “两件事物”。但是,如果有的话   嵌套捕获子模式,   相应的捕获值可能有   已在先前的迭代中设置。对于   例如,在/(a |(b))+ /匹配之后   “aba”捕获的第二个值   substring是“b”。