Frage

Ich habe ein Array voll von Mustern, die ich abgestimmt müssen. Jede Art und Weise zu tun, dass, anders als ein für () Schleife? Im Versuch, es in der am wenigsten CPU intensiven Art und Weise zu tun, da ich Dutzende von diesen jeder Minute werde zu tun.

Ein echtes Beispiel ist, Im einen Link Statuskontrolleur Gebäude, die Links zu verschiedenen Online-Video-Websites überprüfen wird, um sicherzustellen, dass die Videos noch leben werden. Jede Domain hat mehr „tote keywords“, wenn diese im HTML-Code einer Seite zu finden ist, das heißt, die Datei gelöscht wurde. Diese werden in dem Array gespeichert. Ich brauche den Inhalt pf die Anordnung gegen die HTML-Ausgabe auf der Seite entsprechen.

War es hilfreich?

Lösung

Vor allem, wenn man buchstäblich nur tun, Dutzende alle Minuten , dann würde ich nicht sehr über die Leistung in diesem Fall kümmern. Diese Begegnungen sind ziemlich schnell, und ich glaube nicht, dass du gehst zu einem Performance-Problem haben, indem sie durch Ihre Muster Array iterieren und ruft preg_match separat wie folgt aus:

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

Sie können in der Tat alle Muster in eine kombinieren die or Betreiber wie einige Leute mit schlagen, aber nicht nur schlagen sie zusammen mit einem |. Dies bricht schlecht, wenn alle Ihre Muster enthalten der oder Betreiber.

Ich würde zumindest die Gruppierung Ihre Muster empfehlen die Verwendung von Klammern wie:

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

Aber ... ich bin nicht wirklich sicher, ob dies schneller endet als. Etwas hat durch sie Schleife, ob es die preg_match oder PHP ist. Wenn ich, ich würde vermuten, dass einzelne Spiele erraten musste so schnell schließen würden und leichter zu lesen und zu pflegen.

Schließlich, wenn die Leistung ist, was Sie hier suchen, ich denke, das Wichtigste ist, die nicht Regex in eine einfache Spiele zu tun herausziehen „Zeichenfolge“ zu überprüfen. Ich könnte mir vorstellen, dass einige Ihrer Kontrollen einfachen String überprüft werden muss wie der Blick zu sehen, ob „Diese Seite ist geschlossen“ ist auf der Seite.

So tut dies:

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;
  } 
}

und so viele preg_match() wie möglich vermieden wird wahrscheinlich die beste Verstärkung sein würde. strpos() ist ein Los schneller als preg_match().

Andere Tipps

// 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

Wenn Ihr Muster nicht viele Leerzeichen enthalten, wäre eine weitere Option, die Arrays zu vermeiden und die /x Modifikator. Jetzt ist Ihre Liste von regulären Ausdrücken würde wie folgt aussehen:

$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";

Mit dem /x Modifikator wird Leerzeichen vollständig ignoriert, außer wenn in einer Zeichenklasse oder ein Backslash. Kommentare wie oben sind ebenfalls erlaubt.

Dies würde die Schleife durch das Array vermeiden.

Wenn Sie nur sich für das Vorhandensein einer Zeichenfolge in einer anderen Zeichenfolge suchen, verwenden Sie strpos, da es schneller ist.

Sie können sonst nur iterieren über die Anordnung von Mustern, preg_match jedes Mal aufgerufen wird.

Wenn Sie eine Reihe von Mustern haben, was Sie tun können, ist, sie in einem einzigen regulären Ausdruck verketten und dass entsprechen. Keine Notwendigkeit für eine Schleife.

Was ist ein str_replace() auf der HTML machen Sie Ihren Array erhalten und anschließend überprüft, ob die ursprünglichen HTML zum Original gleich sind? Dies wäre sehr schnell:

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

Sie können alle Muster aus der Liste zu einzelnen regulären Ausdruck kombinieren mit implodieren () pHP-Funktion. Dann testen Sie Ihre Zeichenfolge auf einmal mit preg_match () PHP-Funktion.

$patterns = array(
  'abc',
  '\d+h',
  '[abc]{6,8}\-\s*[xyz]{6,8}',
);

$master_pattern = '/(' . implode($patterns, ')|(') . ')/'

if(preg_match($master_pattern, $string_to_check))
{
  //do something
}

Natürlich könnte es auch weniger Code implodieren () inline in "if ()" Bedingung statt $master_pattern variabel.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top