为了账号安全,请及时绑定邮箱和手机立即绑定

Preg_match_all() - 正则表达式太大

Preg_match_all() - 正则表达式太大

PHP
慕慕森 2022-07-09 16:30:56
我怎样才能改进以下preg_match_all模式,所以我没有这个警告:preg_match_all():编译失败:正则表达式在偏移量 32036 处太大    $sql = "SELECT skills FROM weighted_skills_industry     WHERE industry = 'Engineering' ORDER by LENGTH(skills) DESC LIMIT 3000";    $result = $con->query($sql);     while($row = $result->fetch_assoc()) {         $skill[] = $row['skills'];      }        $pattern = '~(?<![\w-])(?:' . implode('|', array_map(function($i) { return preg_quote($i, '~'); }, $skill)) . ')(?![\w-])~i';        if (preg_match_all($pattern, $text, $matchWords)) {          //write something        }
查看完整描述

2 回答

?
慕莱坞森

TA贡献1810条经验 获得超4个赞

我可能会改用以下查询:


SELECT skills

FROM weighted_skills_industry 

WHERE

    industry = 'Engineering' AND

    skills REGEXP CONCAT('[[:<:]]', ?, '[[:>:]]')

ORDER BY

    LENGTH(skills) DESC

LIMIT 3000;

对于?占位符,您可以绑定$textPHP 代码中的变量。上述逻辑将返回文本中可以找到的所有技能。


查看完整回答
反对 回复 2022-07-09
?
郎朗坤

TA贡献1921条经验 获得超9个赞

如果我理解正确,您将从数据库中获取技能列表(作为关键字数组),并希望检查字符串是否$text包含这些单词中的任何一个。


您现在使用的可能是要走的路,但我怀疑如果您有数千个这样的单词,您是否可以缩短正则表达式。


您可以简单地遍历关键字并对每个关键字执行正则表达式检查。这有点慢,但只要找到任何单词(如果需要),您就可以打破循环:


foreach ($skills as $skill) {

  if (preg_match('~(?<![\w-])(?:' . preg_quote($skill, '~') . ')(?![\w-])~i', $text, $matches)) {

    // do stuff with $matches[0] (found keyword)

    // ...

    break; // <- if finding one of these words is enough

  }

}

请注意,您还可以\b在正则表达式中使用来检查单词边界。考虑:


\bword\b

代替:


(?<![\w-])word(?![\w-])

或者,有一些方法可以增加模式大小限制,但您必须重新编译 PHP。


查看完整回答
反对 回复 2022-07-09
  • 2 回答
  • 0 关注
  • 95 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信