2013-10-19 29 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