3

テストするこの文字列があり、思い通りに動作させることができません:

<?php
$string = '500 or fatal error ?';
$regex = '#(fatal|500)#';
if (preg_match($regex, $string, $return)) {
    // Return 500
    echo $return[1];
}
?>

これが最初のセレクターであるため、スクリプトが 500 ではなく Fatal を返すようにします。出来ますか ?

前もって感謝します。下手な英語で申し訳ありません。

PS : 私のタイトルがはっきりしないかもしれませんが、どう説明すればよいかわかりません。見つけたら交換しましょう。

4

3 に答える 3

2

text-directed engines正規表現エンジンには、とエンジンの2種類がありますregex-directed

phpはregex-directed、「500」の一致が後で見つかった場合でも、常に左端の一致を返すエンジンです。

エンジンは文字列の最初の文字から起動します。最初の文字で正規表現の可能なすべての順列を試します。すべての可能性が試されて失敗した場合にのみ、エンジンはテキストの2番目の文字で続行します。繰り返しになりますが、正規表現のすべての可能な順列をまったく同じ順序で試行します。その結果、正規表現指向のエンジンは左端の一致を返します。

あなたはここでより多くの情報を見つけることができます

于 2013-03-19T16:58:01.340 に答える
2

あなたが思い描いているようには不可能ですが、別の実装でうまくいくでしょう

$string = '500 or fatal error';
$regexes = array('#\bfatal\b#', '#\b500\b#');

$match = null;
foreach ($regexes as $re)
  if (preg_match($re, $string, $match))
    break;
# $match is null -> not found
于 2013-03-19T17:01:16.587 に答える
2

正規表現を 1 つだけ使用する場合は、次のようにします。

$selectors = array( 'fatal', '500'); // Array of selectors (in priority order)

$delimiter = '/';
$regex = $delimiter . '(' . implode('|', array_map( 'preg_quote', $selectors, array_fill( 0, count( $selectors), '/'))) . ')' . $delimiter;
preg_match_all( $regex, $string, $matches);

配列の順に、見つかったセレクターを確認します。

$found_selectors = array_flip( $matches[1]);
foreach( $selectors as $selector) { 
    if( isset( $found_selectors[$selector])) 
        return $selector;
}

両方とも線形検索を行う/を実行する代わりに、配列を反転して、$matches[1]配列への一定のルックアップ時間を取得していることに注意してください。array_search()in_array()

このデモfatalから、入力文字列を指定すると、が生成されることがわかります。

于 2013-03-19T17:10:13.967 に答える