PHP preg_replace:忽略替换值中的匹配项

时间:2013-10-19 15:01:33

标签: php preg-replace

我想用preg_replace用值替换主题中的标记。 主题中的标记是问号或命名参数。 (想想PDO风格)

我当前的方法运行正常,直到其中一个值包含问号本身。 (或者命名变量。)在这种情况下,整个系统变坏:被替换值中的问号本身被下一个值替换。

基本上,我不想替换$ values数组中的任何内容。所以preg_replace的“递归”性质就是我想要停止的。

最好的方法是什么?

孤立的例子:

<?php

// Values that will be replaced
$values = array (1, 2, 'bla bla ? bla', 'NULL', 4, 'woop woop', 'waap waap');

// Keys used for replacing
$keys = array ('/[?]/', '/[?]/', '/[?]/', '/[?]/', '/[?]/', '/:testvar1/', '/:testvar2/');

// Original text
$original = ":testvar1, ?, ?, ?, ?, ?, :testvar2";

// Actual replaced text
$actual = preg_replace ($keys, $values, $original, 1);

// Expected replaced text
$expected = "woop woop, 1, 2, bla bla ? bla, NULL, 4, waap waap";

echo '<pre>';
echo "Actual:\n";
echo $actual . "\n\n";
echo "Expected:\n";
echo $expected . "\n\n";
echo "Result:\n";

if ($actual == $expected)
{
    echo '<span style="color: green;">Success!</span>';
}
else
{
    echo '<span style="color: red;">Failure!</span>';   
}

任何提示? :-) 谢谢!

2 个答案:

答案 0 :(得分:0)

这可以通过前瞻断言来解决,如下所示:

// Keys used for replacing
$keys = array ('/\?(?=,)/', '/\?(?=,)/', '/\?(?=,)/', '/\?(?=,)/', '/\?(?=,)/');

这将使RE引擎匹配任何问号后跟逗号,不带使逗号成为匹配的一部分。但是,如果您的替换值包含问号后跟逗号,则会再次遇到这种情况。

答案 1 :(得分:0)

使用preg_replace_callback,您可以手动指定替换项,如下所示:

$values = [1,2,'bla bla ? bla','NULL',4];
$original = "?, ?, ?, ?, ?";
$actual = preg_replace_callback("/[?]/",function($m) use (&$values) {
    return array_shift($values);
});

完成!