【问题标题】:PHP Regexp Optimize An Existing PatternPHP Regex 优化现有模式
【发布时间】:2018-08-10 19:54:39
【问题描述】:

我正在使用此代码

preg_match_all("/([^#]+\btbds\b.+?)#/iu", $data, $matches);   

查找所有名为 tbds 的单词,但执行模式搜索大约需要 1.20 秒。如果我只使用 tbds\b 而不是 \btbds\b 只需 0.19 秒(少 6 倍)。

preg_match_all("/([^#]+tbds\b.+?)#/iu", $data, $matches); 

有什么方法可以优化单词匹配 \btbds\b 以花费大约 0.19 秒?我需要处理大量数据。

这里是测试代码:

function generateRandomString($length = 10) {
    $characters = ' 0123 456 789 abcd efgh ijkl mn opqrstu vwx yzAB CDE FGHI JKL MNOP QRS TUVWX YZ';
    $charactersLength = strlen($characters);
    $randomString = '';
    for ($i = 0; $i < $length; $i++) {
        $randomString .= $characters[rand(0, $charactersLength - 1)];
    }
    $randomString = preg_replace('/\s+/', ' ', $randomString);
    return trim($randomString,' ');
}


$data=NULL;
for ($a = 1; $a < 1000000; $a++) 
    $data.=" ".generateRandomString(100)." #";


$t = microtime(true);
preg_match_all("/([^#]+\btbds\b.+?)#/iu", $data, $matches); 
echo microtime(true) - $t; echo "\n";

【问题讨论】:

  • 我需要处理大量数据。欢迎任何帮助:)
  • 那么,你想对这么大量的数据做什么,为什么必须快速完成呢?如果我们知道您想要达到的目标,也许它可以激励我们帮助您?换句话说:我们如何优化我们一无所知的东西?
  • 请注意,它们不匹配,因为没有\b 的匹配atbds #,而另一个则不会
  • 可能会尝试另一种方法:$res = preg_grep('/\btbds\b/i', explode("#", $data));
  • @Miguel 也许您可以帮助我们了解您的真实输入数据,因为您随机生成的内容永远不会找到匹配项——没有生成# 符号。如果您希望我们为您设计优化模式,我们需要充分了解输入可变性。此外,您正在执行 unicode 匹配,但没有提供 unicode 字符。请改进您的问题。

标签: php regex preg-match preg-match-all


【解决方案1】:

也许这有可能匹配#,然后使用\K 重置报告匹配的起点。

然后在[^#]+tbds 之间的单词边界\btbds\b 之间不匹配# 一次或多次。

#\K[^#]+\btbds\b[^#]+#

【讨论】:

  • 感谢您的回答。我刚刚测试了您的建议,它的性能似乎与原始 /([^#]+\btbds\b.+?)#/iu 相似
  • @Miguel 你有没有比较几个例子在 regex101 上的步数?
  • 是的,与原来相比,它的步骤很少,但就运行测试代码时的性能而言,我在 1.20 左右得到类似的执行时间
【解决方案2】:

让你的正则表达式变慢的是前面的[^#]+

如果您定义一个可以是 #字符串开头 的起点,可能会有所帮助:

/(?:(?<=#)|^)([^#]*\btbds\b.+?)#/iu

The Demo

【讨论】:

  • 我刚刚测试了你的答案,大约需要 1.20 秒。
  • 我在 regex101 对其进行了测试,它需要大约 1/10 步,并且在 php 测试站点上使用您的基准测试它似乎也快得多:)
  • 嗨,你的正则表达式 /(?:(?
猜你喜欢
  • 2020-02-23
  • 2011-12-26
  • 1970-01-01
  • 1970-01-01
  • 2013-12-05
  • 1970-01-01
  • 2011-01-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多