我有一个数组充满,我需要匹配的模式。任何方式做到这一点,比for()循环其他?林试图做到这一点的至少CPU密集型方式,因为我会做这些数十每一分钟。

现实世界的例子是,林建一个链接状态检查,这将检查到各种在线视频网站,以确保影片仍然活着。每个域都有几个“死关键字”,如果这些都在一个页面的HTML,这意味着该文件已被删除找到。这些被存储在数组中。我需要的内容相匹配的阵列PF,对页面的HTML输出。

有帮助吗?

解决方案

首先,如果你从字面上只是做几十分钟,然后我就并不十分担心在这种情况下的性能。这些比赛是相当快的,我不认为你会通过你的模式阵列迭代,并分别调用的preg_match这样有一个性能问题:

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

您可以使用确实像有些人or运营商所提出的建议所有的图案合并为一个,但不只是一个|拍在一起。这将破坏严重,如果你的任何图案的包含 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()更快。

其他提示

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

如果你的模式不包含许多空格,另一种选择是避开了阵列和使用/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改性剂,空白完全被忽略,在字符类或当由反斜杠除外。像上面评论也是允许的。

这将避免通过阵列的循环。

如果你只是寻找在另一个字符串字符串的存在,使用strpos因为它是更快的。

否则,你可以只迭代图案的阵列上,调用的preg_match各一次。

如果你有一大堆的模式,你所能做的就是将它们连接在一个单一的正则表达式匹配。没有必要为一个循环。

怎么样在您开始使用数组,然后检查是否原始的HTML等于原有的HTML做str_replace()?这将是非常快:

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

可以从使用破灭列表以单一正则表达式(组合所有图案) PHP函数。然后,在一次使用的preg_match() PHP函数测试你的字符串。

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

当然有可能在“如果()”条件,而不是$master_pattern可变使用内爆()内联甚至更少的代码。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top