2013-03-16 8 views
67

正規表現はひどいです。私はこれを置き換えようとしています:preg_replace()e修飾子をpreg_replace_callbackに置き換えてください。

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

匿名機能を持つpreg_replace_callbackです。 \\ 2が何をしているのか分かりません。それとも、正確にどのようにpreg_replace_callbackが動作するかについてです。

これを達成するための正しいコードは何でしょうか?

+1

** E(http://php.net/manual/en/reference.pcre.pattern.modifiers.php)PHPのよう5.5.0私は – HamZa

+8

@HamZaDzCyber​​DeVを知ります。これがpreg_replace_callbackに置き換えたい理由の1つです – Casey

+2

['preg_replace_callback'](http://php.net/preg_replace_callback)のマニュアルページがあります。そして、コールバックで '\\ 2'は' $ matches [2] 'になります。または、あなたは具体的にどの部分を混乱させていますか? – mario

答えて

59

正規表現では、一致した文字列の一部を(brackets)で「取得」できます。この場合、あなたは(^|_)([a-z])の部分をキャプチャしています。これらは1から始まる番号が付けられているので、バックリファレンス1と2があります。Match 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]); } 
0になる可能性になる可能性

$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へのコールを削除することをお勧めします。修飾子が[非推奨]れる**
関連する問題