preg_replace将意外结果返回到$ 1

时间:2013-05-01 21:37:05

标签: php regex preg-replace

<?php
$data='123
[test=abc]cba[/test]
321';
$test = preg_replace("(\[test=(.+?)\](.+?)\[\/test\])is","$1",$data);
echo $test;
?>

我希望上面的代码能够返回 abc 但不是返回abc而是返回 123 abc 321 请告诉我我做错了什么。

3 个答案:

答案 0 :(得分:1)

您只是替换匹配的部分(BBcode部分)。你要保持弦乐的其余部分不受影响。

如果您还想删除前导/尾随文本,请在表达式中包含这些文本:

$test = preg_replace("(.*\[test=(.+?)\](.+?)\[\/test\].*)is","$1",$data);

答案 1 :(得分:1)

我不知道你是否意识到这一点,但你的正则表达式中最外面的一组括号不会形成一个组(捕获或其他)。 PHP将它们解释为regex delimiters。如果您 意识到这一点,并且您有意将它们用作分隔符,请不要。通常最好使用在正则表达式中没有任何特殊含义的非包围字符(~%@等。)

我同意Casimir preg_match()是您应该使用的工具,而不是preg_replace()。但他的解决方案比它需要的更棘手。你的原始正则表达式正常;您所要做的就是抓住第一个捕获组的内容,如下所示:

if (preg_match('%\[test=(.+?)\](.+?)\[/test\]%si', $data, $match)) {
    $test = $match[1];
}

答案 2 :(得分:0)

你不需要在这里使用替换,你需要的只是在字符串中取一些东西。要做到这一点,preg_match更有用:

$data='123
[test=abc]cba[/test]
321';
$test = preg_match('~\[test=\K[^\]]++~', $data, $match);
echo $match[0];