2013-03-16 133 views
67

用正則表達式來說我很糟糕。我試圖替換它:用preg_replace_callback替換preg_replace()e修飾符

public static function camelize($word) { 
    return preg_replace('/(^|_)([a-z])/e', 'strtoupper("\\2")', $word); 
} 

with preg_replace_callback with anonymous function。我不明白'2'在做什麼。或者就此而言,preg_replace_callback是如何工作的。

實現此目的的正確代碼是什麼?

+1

的** **ë改性劑(已廢棄)(http://php.net/manual/en/reference.pcre.pattern.modifiers.php)作爲PHP的5.5.0 – HamZa 2013-03-16 20:17:45

+8

@HamZaDzCyber​​DeV我知道。這是我想用preg_replace_callback – Casey 2013-03-16 20:18:58

+2

取代它的​​原因之一。['preg_replace_callback'](http://php.net/preg_replace_callback)有一個手冊頁。在該回調中'\\ 2'將變成'$ matches [2]'。或者你特別困惑哪一部分? – mario 2013-03-16 20:20:53

回答

59

在正則表達式中,您可以用「(brackets)」捕獲部分匹配的字符串;在這種情況下,您正在捕獲(^|_)([a-z])部分比賽。它們從1開始編號,所以你有反向引用1和2.匹配0是整個匹配的字符串。

/e修改需要一個替換字符串和替代反斜線後面的數字(例如\1)與適當的反向參考 - 而是因爲你是一個字符串中,你需要轉義反斜線,讓您得到'\\1' 。然後它(有效)運行eval來運行結果字符串,就像它是PHP代碼一樣(這就是爲什麼它被棄用的原因,因爲它易於以不安全的方式使用eval)。

preg_replace_callback函數改爲使用回調函數並將其傳遞給包含匹配反向引用的數組。因此,如果你寫了'\\1',你可以訪問該參數的元素1 - 例如如果您有function($matches) { ... }形式的匿名函數,則該函數內的第一個後向引用是$matches[1]

所以

'do_stuff(\\1) . "and" . do_stuff(\\2)' 

一個/e爭論可能會成爲

function($m) { return do_stuff($m[1]) . "and" . do_stuff($m[2]); } 

或者回調你的情況

'strtoupper("\\2")' 

可能成爲

function($m) { return strtoupper($m[2]); } 

請注意$m$matches不是神奇的名字,它們只是我在聲明回調函數時給出的參數名稱。此外,您不必傳遞匿名函數,它可以是函數名稱作爲字符串,或者可以是array($object, $method),as with any callback in PHP等形式。

function stuffy_callback($things) { 
    return do_stuff($things[1]) . "and" . do_stuff($things[2]); 
} 
$foo = preg_replace_callback('/([a-z]+) and ([a-z]+)/', 'stuffy_callback', 'fish and chips'); 

與任何函數一樣,默認情況下,您不能在回調之外(來自周圍範圍)訪問變量。當使用匿名函數時,您可以使用use關鍵字導入您需要訪問的變量,as discussed in the PHP manual。例如如果舊的說法是

'do_stuff(\\1, $foo)' 

那麼新的回調可能看起來像

function($m) use ($foo) { return do_stuff($m[1], $foo); } 

陷阱

  • preg_replace_callback使用是而不是/e修改的正則表達式,所以你需要從你的「模式」參數中刪除該標誌。所以像/blah(.*)blah/mei這樣的模式將變成/blah(.*)blah/mi
  • /e修飾符在參數內部使用了addslashes()的變體,所以一些替換使用stripslashes()來刪除它;在大多數情況下,您可能希望從新回叫中刪除對stripslashes的呼叫。
相關問題