这是一个棘手的问题,我有一个字符串:
This is some text with a {%TAG IN IT%} and some more text then {%ANOTHER TAG%} with some more text at the end.
我有一个匹配标签的正则表达式:
({%\w+[\w =!:;,\.\$%"'#\?\-\+\{}]*%})
将匹配起始标记与任何字母数字字符,后跟任意数量的其他ansi字符(上述正则表达式中指定的样本集)。
但是(在PHP中使用“preg_match_all”和“preg_split”至少)该集合同时包含百分比(%)和花括号({如果同一行上有两个标记,则表示正则表达式匹配太多。
例如,在给出的示例中,匹配以下内容:
{%TAG IN IT%} and some more text then {%ANOTHER TAG%}
如您所见,%} ... {%匹配。所以,我需要的是允许“%”但不是在“}”后面
我尝试过非reedy匹配和负向前瞻,但负向前瞻不会在字符集中起作用(即[\ w ...] *集中的所有内容)。
我被困住了!
答案 0 :(得分:1)
您可以使用轮换来实现此目的:
/\{%(?:[^%]|%(?!}))*%\}/
匹配不是%
的字符或未跟}
的字符(使用前瞻assertion)。
$str = 'This is some text with a {%tag with % and } inside%} and some more text then {%ANOTHER TAG%} with some more text at the end.';
$pattern = '/\{%(?:[^%]|%(?!}))*%\}/';
preg_match_all($pattern, $str, $matches);
print_r($matches[0]);
输出:
Array
(
[0] => {%tag with % and } inside%}
[1] => {%ANOTHER TAG%}
)
答案 1 :(得分:0)
对正则表达式稍作修改(只需添加问号即可使其非贪婪) -
<?php
$input = "This is some text with a {%TAG % }IT%%} and some more text then {%ANOTHER TAG%} with some more text at the end.";
$regexp = "/{%\w+[\w =!:;,\.\$%\"'#\?\-\+\{}]*?%}/";
// ^ Notice this
if(preg_match_all($regexp, $input, $matches, PREG_SET_ORDER)) {
foreach($matches as $match) {
var_dump($match);
echo "\r\n";
}
unset($match);
}
/*
Outputs:
array
0 => string '{%TAG % }IT%%}' (length=14)
array
0 => string '{%ANOTHER TAG%}' (length=15)
*/
?>