2009-03-25 13 views
6

私は、必要なパターンでいっぱいの配列を持っています。 for()ループ以外の方法はありますか?私が毎分これらの数十をやっているので、私はCPUの集中的な方法でそれをやろうとしています。preg_matchは、パターンがPHPの配列の場合、どのように実行しますか?

現実世界の例は、さまざまなオンライン動画サイトへのリンクをチェックして、動画がまだ生きていることを確認するリンクステータスチェッカーを作成することです。各ドメインにはいくつかの「死んだキーワード」があります。これらのキーワードがページのhtmlにある場合、そのファイルが削除されたことを意味します。これらは配列に格納されます。配列の内容とページのhtml出力を一致させる必要があります。

答えて

20

まず第一に、あなたは文字通りのみ何十すべてのを行っている場合は、その後、私はこのケースでパフォーマンスについてそれほど心配しないでしょう。これらの試合はかなり速いです、と私はあなたのパターンの配列を反復処理し、別にこのようするpreg_matchを呼び出すことにより、パフォーマンスの問題を持っているつもりだとは思わない:

$matches = false; 
foreach ($pattern_array as $pattern) 
{ 
    if (preg_match($pattern, $page)) 
    { 
    $matches = true; 
    } 
} 

あなたが本当に一つに、すべてのパターンを組み合わせることができますいくつかの人々のようにor演算子を使用して、示唆しているだけで一緒に|を叩かないでください。あなたのパターンのいずれかがに含まれている場合、これはひどく壊れますまたは演算子。

私は次のように括弧を使用してパターンをグループ化し、少なくとも推薦:

foreach ($patterns as $pattern) 
{ 
    $grouped_patterns[] = "(" . $pattern . ")"; 
} 
$master_pattern = implode($grouped_patterns, "|"); 

しかし...私はこれが速くなってしまう場合は本当にわかりません。 何かはpreg_matchかPHPかに関わらず、それらをループする必要があります。私が推測しなければならなかったのは、個々の試合が速くて読みやすく、維持しやすいと思います。

最後に、パフォーマンスがここで探しているものであれば、最も重要なのは、正規表現以外のマッチを単純な「文字列を含む」チェックに引き出すことだと思います。私はあなたの小切手のいくつかは、 "This Site is Closed"がページにあるかどうかを調べるような簡単な文字列チェックでなければならないと思います。

だから、このやって:

foreach ($strings_to_match as $string_to_match) 
{ 
    if (strpos($page, $string_to_match) !== false)) 
    { 
    // etc. 
    break; 
    } 
} 
foreach ($pattern_array as $pattern) 
{ 
    if (preg_match($pattern, $page)) 
    { 
    // etc. 
    break; 
    } 
} 

をし、できるだけ多くのpreg_match()を回避することはおそらくあなたの最善の利益になるだろう。 strpos()ロットで、preg_match()より速い。

+4

Google社員のために、マッチを見つけたら、foreachループから脱出するためにbreak(http://www.php.net/manual/en/control-structures.break.php)を使用することを検討してください!あなたのコメントに対処するために編集され、少なくともPHP –

+2

私はこれがあるべきと考えています。 – hellomynameisjoel

+1

さてさて君たちの私のバージョンでのforeach($パターンとしての$ pattern_array)、...: – danieltalsky

0

パターンがたくさんある場合は、それらを1つの正規表現で連結して一致させることができます。ループの必要はありません。

1

文字列が他の文字列内に存在するかどうか検索する場合は、strposを使用する方が高速です。

そうしないと、毎回preg_matchを呼び出すだけでパターンの配列を繰り返し処理できます。

10
// assuming you have something like this 
$patterns = array('a','b','\w'); 

// converts the array into a regex friendly or list 
$patterns_flattened = implode('|', $patterns); 

if (preg_match('/'. $patterns_flattened .'/', $string, $matches)) 
{ 
} 

// PS: that's off the top of my head, I didn't check it in a code editor 
+1

「パターン」のまわりのかっこ/括弧なしで動作しますか? – JedatKinports

0

HTMLでstr_replace()を実行すると、元のHTMLと元のHTMLが同じであるかどうかを確認してください。これは非常に高速になります:

$sites = array(
     'you_tube' => array('dead', 'moved'), 
     ... 
); 
foreach ($sites as $site => $deadArray) { 
    // get $html 
    if ($html == str_replace($deadArray, '', $html)) { 
     // video is live 
    } 
} 
+0

完全一致が必要な場合はstr_replaceが機能していません –

2

あなたのパターンは多くの空白が含まれていない場合は、別のオプションは、配列を避け、/x修飾子を使用することです。さて、正規表現のリストは、次のようになります。/x修飾子で

$regex = "/ 
pattern1| # search for occurences of 'pattern1' 
pa..ern2| # wildcard search for occurences of 'pa..ern2' 
pat[ ]tern| # search for 'pat tern', whitespace is escaped 
mypat  # Note that the last pattern does NOT have a pipe char 
/x"; 

、空白は完全に文字クラスやバックスラッシュが先行する場合を除き、無視されます。上記のようなコメントも許可されます。

これは、アレイのループを回避します。

関連する問題