2011-07-03 55 views
3

我有一些替代應用在我的$問題,但我不希望從老換人#輸出(1 .. I-1)是當前替代匹配#一世。的preg_replace使用多種模式替換一次

$subject1 = preg_replace($pat0, $rep0, $subject0); 
$subject2 = preg_replace($pat1, $rep1, $subject1); 
$subject3 = preg_replace($pat2, $rep2, $subject2); 

我試圖用一個的preg_replace與模式和替換希望它使它在一次陣列;但事實證明是不低於調用簡單的preg_replace先後(當然是有一些優化)

我越瞭解preg_replace_callback後,我想這是不是一個解決方案。

任何幫助?

回答

3

使用回調函數,您可以檢測使用捕獲組匹配哪個模式,如(?:(patternt1)|(pattern2)|(etc),只會定義捕獲組的匹配模式。

與唯一的問題是,當前的捕獲組將被轉移。修復(閱讀解決方法)您可以使用命名組。 (A分支重新(?|(foo)|(bar))將工作(如果支持您的版本),但你不得不檢測其模式已經使用一些其他的方式匹配。)

function replace_callback($matches){ 
    if(isset($matches["m1"])){ 
     return "foo"; 
    } 
    if(isset($matches["m2"])){ 
     return "bar"; 
    } 
    if(isset($matches["m3"])){ 
     return "baz"; 
    } 
    return "something is wrong ;)"; 
} 

$re = "/(?|(?:regex1)(?<m1>)|(?:reg(\\s*)ex|2)(?<m2>)|(?:(back refs) work as intended \\1)(?<m3>))/"; 

$rep_string = preg_replace_callback($re, "replace_callback", $string); 

未測試(這裏沒有PHP),但是像這樣的東西可以工作。

+0

謝謝你的答案。我已經按照@leonbloy的回答在沒有命名組的情況下完成了它。但是如果你展示瞭如何使用命名組,這將非常棒。 – mmonem

+0

@mmonem,增加了一個例子。 – Qtax

+0

謝謝你的例子。這比我做的更簡單。 – mmonem

1

在我看來,這是preg_replace_callback最直接的解決方案。你只用|運營商指定備用模式和回調裏面,你編寫一個ifswitch。似乎正確的方式給我。你爲什麼丟棄它?

另一種解決方案是使一個臨時更換到一個特殊的字符串。你說:

// first pass 
$subject = preg_replace($pat0, 'XXX_MYPATTERN0_ZZZ', $subject); 
$subject = preg_replace($pat1, 'XXX_MYPATTERN1_ZZZ', $subject); 
$subject = preg_replace($pat2, 'XXX_MYPATTERN2_ZZZ', $subject); 
// second pass 
$subject = preg_replace("XXX_MYPATTERN0_ZZZ",$rep0 , $subject); 
$subject = preg_replace("XXX_MYPATTERN1_ZZZ",$rep1 , $subject); 
$subject = preg_replace("XXX_MYPATTERN2_ZZZ",$rep2 , $subject); 

這是非常醜陋的,沒有很好地適應動態替代,它不是萬無一失的,但對於一些「運行一次」的劇本可能是可以接受的。

+0

非常感謝您的回答。現在我要學習你的第一個解決方案,因爲我喜歡這個主意 – mmonem

+0

謝謝,我做了以下的想法,但我接受@Qtax的答案,因爲他給了更多的解釋,並提供了完整的例子 – mmonem