2013-10-19 30 views
2

我想使用preg_replace替换具有值的主题中的令牌。 主题中的令牌是问号或命名参数。 (认为​​PDO风格)PHP preg_replace:忽略替换值中的匹配

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

基本上,我不想替换在$ 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>'; 
} 

任何提示吗? :-) 谢谢!

回答

0

这可能与向前断言来解决,就像这样:

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

这将使RE发动机匹配任何问号后跟一个逗号,没有使逗号比赛的一部分。但是,如果您的替换值包含问号和逗号,您将再次遇到这种情况。

+0

这并没有解决问题,它只是推回来。如果替换包含'?,'会怎么样? –

+0

“但是,如果您的替换值包含问号后跟逗号,则会再次遇到此情况。” – InitHello

+0

所以你知道这个问题......你会如何解决它? –

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); 
}); 

完成!

+0

你说得对,那就解决了最初的问题。然而,钥匙必须是当时的产品。这个问题可能不是很明显,但$ keys数组也可以不同。将编辑原来的问题,抱歉的困惑:) – daedeloth

+0

我已经完成了这个场景。我也尝试过preg_replace_callback,但与不同的顺序它完全疯狂:) – daedeloth