10

一致させる必要のあるパターンでいっぱいの配列があります。for()ループ以外の方法はありますか?私は毎分何十ものこれらを実行するので、CPUを最も集中的に使用しない方法でそれを実行しようとしています。

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

4

7 に答える 7

24

まず第一に、文字通り毎分数十回しか実行していない場合、この場合のパフォーマンスについてそれほど心配する必要はありません。これらの一致は非常に迅速であり、次のようにパターン配列を反復処理して preg_match を個別に呼び出すことで、パフォーマンスの問題が発生するとは思いません。

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

or実際、一部の人が提案しているように、演算子を使用してすべてのパターンを 1 つに結合できますが、 |. パターンのいずれかにor 演算子が含まれていると、これはひどく壊れます。

少なくとも次のような括弧を使用してパターンをグループ化することをお勧めします。

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

しかし...これがより高速になるかどうかはよくわかりません。 preg_match であろうと PHP であろうと、何かがそれらをループする必要があります。推測する必要がある場合、個々の一致はほぼ同じくらい速く、読みやすく、維持しやすいと思います。

最後に、パフォーマンスがここで求めているものである場合、最も重要なことは、正規表現以外の一致を単純な「文字列を含む」チェックに引き出すことだと思います。あなたのチェックのいくつかは、「このサイトは閉鎖されています」がページにあるかどうかを確認するなどの単純な文字列チェックでなければならないと思います.

これを行う:

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()

于 2009-03-25T23:56:15.427 に答える
14
// 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
于 2009-03-25T22:25:43.227 に答える
3

パターンに多くの空白が含まれていない場合、配列を避けて/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";

修飾子を使用/xすると、文字クラス内または前にバックスラッシュがある場合を除いて、空白は完全に無視されます。上記のようなコメントも許可されます。

これにより、配列のループが回避されます。

于 2012-09-10T14:14:45.407 に答える
1

別の文字列内の文字列の存在を単に検索する場合は、より高速な strpos を使用してください。

それ以外の場合は、毎回 preg_match を呼び出して、パターンの配列を反復処理することができます。

于 2009-03-25T22:23:32.843 に答える
0

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

于 2009-03-25T22:12:36.830 に答える
0

配列を使用して取得した HTMLに対して aを実行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
     }
 }
于 2009-03-26T00:17:16.877 に答える