我正在尝试匹配这样的字符串:
{{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
答案 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”。