你如何执行的preg_match其中模式是一个数组,在PHP?
-
22-08-2019 - |
题
我有一个数组充满,我需要匹配的模式。任何方式做到这一点,比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
可变使用内爆()内联甚至更少的代码。