【问题标题】:splitting long regex to pieces PHP将长正则表达式拆分为 PHP
【发布时间】:2020-12-31 05:40:58
【问题描述】:

我有一个很长的名称列表,如果列表中的名称在字符串中的任何位置,我将使用 preg_replace 进行匹配。如果我在正则表达式中使用很少的名称对其进行测试,它可以正常工作,但考虑到我有超过 5000 个名称,它会给我错误“preg_replace():编译失败:正则表达式太大”。

不知何故,我无法弄清楚如何将正则表达式分成几部分,使其变得更小(如果可能的话)。

名称列表是从数据库动态创建的。 这是我的代码。

$query_gdpr_names = "select name FROM gdpr_names";
$result_gdpr_names = mysqli_query($connect, $query_gdpr_names);
    
while ($row_gdpr_names = mysqli_fetch_assoc($result_gdpr_names))
{
  $AllNames .= '"/'.$row_gdpr_names['name'].'\b/ui",';
}
$AllNames = rtrim($AllNames, ',');
$AllNames = "[$AllNames]";
$search = preg_replace($AllNames, '****', $search);

创建的 $AllNames str 如下所示(仅在示例中 3 个名称)

$AllNames = ["/Lola/ui", "/Monica\b/ui", "/Chris\b/ui"];

还有测试字符串

$search = "I am Lola and my friend name is Chris";

非常感谢任何帮助。

【问题讨论】:

    标签: php regex preg-replace


    【解决方案1】:

    由于您似乎无法使用单个正则表达式替换从 PHP 轻松处理替换,因此一种替代方法是逐个迭代结果集中的每个名称并进行替换:

    while ($row_gdpr_names = mysqli_fetch_assoc($result_gdpr_names)) {
        $name = $row_gdpr_names['name'];
        $regex = "/\b" . $name . "\b/ui";
        $search = preg_replace($regex, '----', $search);
    }
    
    $search = preg_replace("/----/", '****', $search);
    

    这不是最有效的模式。也许有一些方法可以限制你的结果集以避免太长的单次交替。

    【讨论】:

    • 如果列表中有两个匹配的名称。另外,名称前的\b是什么原因?
    • 如果列表中有两个匹配的名字,那么两者都将被替换为****。如果同样的情况发生两次,那么这两个实例都将被替换。
    • 如果我尝试在 $search 为空时回显它。
    • 我的猜测是你的数据有问题。只有当$search 字符串中的每个单词都与某个名称匹配时,您所看到的才有可能。但是,即使那样,也应该有一些剩余的空白。
    • 不,如果我在 while 内打印它,它会显示每个周期并且它是正确的。但是在外面打印只是空的
    【解决方案2】:

    好的,我调试了很多。甚至隔离除这部分代码之外的所有其他内容

    $search = "Lola and Chris";
            $query_gdpr_names = "select * FROM gdpr_names";
                $result_gdpr_names = mysqli_query($connect, $query_gdpr_names);
                        while ($row_gdpr_names = mysqli_fetch_assoc($result_gdpr_names)) {
                            $name = $row_gdpr_names['name'];
                            $regex = "/\b" . $name . "\b/ui";
                            $search = preg_replace($regex, '****', $search);
                            
                        }
                    echo $search;
    

    不过,在循环内部而不是外部打印。

    【讨论】:

    • 我想我知道问题可能出在哪里。 * 是一个正则表达式元字符,因此从循环的第二次迭代开始,第一次替换中的任何**** 都将具有特殊含义。
    • 还是一样。这是一个绝对的谜。
    • 我只是发现它不仅仅适用于 preg_replace。如果我用 str_replace 更改它,它将成功打印。问题是 str_replace 实际上会替换它找到名称的所有位置,即使它位于单词的中间。
    【解决方案3】:

    问题实际上出在数据库记录中。其中一条记录有斜线

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-17
      • 2016-12-03
      • 2018-02-05
      • 2010-11-03
      • 2011-12-21
      相关资源
      最近更新 更多