Php foreach和preg_匹配大量数据,但工作不正常

Php foreach和preg_匹配大量数据,但工作不正常,php,regex,foreach,preg-match,Php,Regex,Foreach,Preg Match,我必须创建一个文件,其中一个充满关键字序列(~20k行),另一个充满正则表达式(~2.5k) 我想用每个regexp测试每个关键字,并打印匹配的关键字。我测试了我的文件,总共进行了大约22750000次测试。我正在使用以下代码: $count = 0; $countM = 0; foreach ($arrayRegexp as $r) { foreach ($arrayKeywords as $k) { $count++; if (preg_match($

我必须创建一个文件,其中一个充满关键字序列(~20k行),另一个充满正则表达式(~2.5k)

我想用每个regexp测试每个关键字,并打印匹配的关键字。我测试了我的文件,总共进行了大约22750000次测试。我正在使用以下代码:

$count = 0;
$countM = 0;
foreach ($arrayRegexp as $r) {
    foreach ($arrayKeywords as $k) {
        $count++;
        if (preg_match($r, $k, $match) {
            $countM++;
            echo $k.' matched with keywords '.$match[1].'<br/>';
        }
    }
}
echo "$count tests with $countM matches.";
$count=0;
$countM=0;
foreach($arrayRegexp作为$r){
foreach($arrayKeywords作为$k){
$count++;
if(预匹配($r,$k,$match){
$countM++;
回显$k.“与关键字“$match[1]”匹配。
; } } } echo“$count测试和$countM匹配。”;
不幸的是,在计算了一段时间后,只显示了部分实际匹配,而保留计数的最后一行从未显示。更奇怪的是,如果我对preg部分进行注释,只保留两个foreach和计数显示,那么一切都正常

我相信这是由于要处理的数据量过多,但我想知道,对于这种操作,是否有我没有遵循的建议。我使用的正则表达式非常复杂,我无法更改为其他形式


有人有想法吗?

增加执行时间

在.htaccess中使用此行

php_value max_execution_time 80000

增加执行时间

在.htaccess中使用此行

php_value max_execution_time 80000

有两个优化选项:

  • 正则表达式通常可以组合成备选方案
    /(regex1 | regex2 | |…)/
    。通常,PCRE评估备选方案的速度比PHP执行循环的速度更快
  • 我不确定这是否更快(修改主题),但可以使用关键字数组作为参数直接preg_replace_callback(),从而消除第二个循环
例如:

 $rx = implode("|", $arrayRegexp);  // if it hasn't /regexp/ enclosures

 preg_replace_callback("#($rx)#", "print", $arrayKeywords);
但是定义一个自定义打印函数来输出和计算结果,并让它只返回一个空字符串


想一想,preg_replace_回调还需要一个正则表达式数组。但不确定它是否交叉检查每个字符串上的每个正则表达式。

有两个优化选项:

  • 正则表达式通常可以组合成备选方案
    /(regex1 | regex2 | |…)/
    。通常,PCRE评估备选方案的速度比PHP执行循环的速度更快
  • 我不确定这是否更快(修改主题),但可以使用关键字数组作为参数直接preg_replace_callback(),从而消除第二个循环
例如:

 $rx = implode("|", $arrayRegexp);  // if it hasn't /regexp/ enclosures

 preg_replace_callback("#($rx)#", "print", $arrayKeywords);
但是定义一个自定义打印函数来输出和计算结果,并让它只返回一个空字符串


想一想,preg_replace_callback还需要一个正则表达式数组。但不确定它是否会交叉检查每个字符串上的每个正则表达式。

您应该显示一个关键字示例(这里的主题实际上是哪个?)还有正则表达式。另外:您是只对匹配计数感兴趣还是对匹配本身感兴趣?显示关键字示例并不重要,因为这只是通过搜索引擎进行的查询。regexp检查查询中是否有特定的产品名称,并显示相应的广告。您缺少一个右括号呃if语句btw@Gaël:你的数据采用什么格式并不完全无关。当人们确切地知道你在使用什么时,他们可能会向你展示一种更有效的方法。此外,为什么它是一个平面文件而不是数据库?你应该展示一个关键字示例(这里的主题实际上是什么?)还有正则表达式。另外:您是只对匹配计数感兴趣还是对匹配本身感兴趣?显示关键字示例并不重要,因为这只是通过搜索引擎进行的查询。regexp检查查询中是否有特定的产品名称,并显示相应的广告。您缺少一个右括号呃if语句btw@Gaël:数据的格式并不是完全不相关的。当人们确切知道您使用的是什么时,他们可能会向您展示一种更有效的方法。此外,为什么它是一个平面文件而不是数据库?或者只是脚本中的
ini_集('max_execution_time',80000);
,我猜
ini_集('max_execution_time',0)
更为正确,因为它允许无限的执行时间。无论如何,这暂时解决了我的问题。谢谢!或者只是
ini_集('max_execution_time',80000);
在脚本中我猜
ini_集('max_execution_time',0);
更正确,因为它允许无限的执行时间。无论如何,这暂时解决了我的问题。谢谢!您的第一个解决方案生成了一个4'000'000字符长的正则表达式字符串,preg_match似乎无法处理这一问题!至于第二个解决方案,它的运行速度似乎没有加快,但快速性不是主题不管怎样,我会记住的!谢谢:-)@Gaël:这是4MB的字符串,一开始就不太容易。Regex可以轻松处理这一点,并且比逐个for循环更有效。虽然增加脚本的执行时间可能会解决您眼前的问题,但很可能存在一种解决方案,它在数量级上优于您的方法。这个答案是指向正确的方向。@Tomalak这就是为什么我接受了这个答案,并指定它是一个临时解决方案。因为在数据收集完成后,我只会执行这个脚本一次或两次,所以它不需要真正的优化,只需工作到文件结束:-)您的第一个解决方案生成一个4'000'000个字符长的正则表达式字符串,preg_match似乎无法处理这个问题!至于第二个解决方案,它似乎没有运行得更快,但无论如何,快速性不是这里的主题。但我会记住这一点!谢谢:-)@Gaël:这是4MB的字符串,一开始就不多了。正则表达式可以很容易地处理这个问题,而且效率更高