preg_match 将关键字变量与本地 UTF-8 编码文件中的拉丁和非拉丁字符关键字列表进行匹配

问题描述 投票:0回答:2

我有一个坏词过滤器,它使用保存在本地 UTF-8 编码文件中的关键字列表。该文件包括拉丁字符和非拉丁字符(主要是英语和阿拉伯语)。对于拉丁关键字,一切都按预期工作,但是当变量包含非拉丁字符时,匹配似乎无法识别这些现有关键字。

如何匹配拉丁语和非拉丁语关键字。

badwords.txt 文件每行包含一个单词,如本例所示



bad

nasty

racist

سفالة

وساخة

جنس

bad

nasty

racist

سفالة

وساخة

جنس

用于匹配的代码:

我读过 iconv、多字节函数(mbstring)和使用运算符 /u 可能对此有所帮助,我尝试了一些方法,但似乎没有得到正确的结果。任何帮助解决这个问题,并让它匹配拉丁和非拉丁关键字的帮助将不胜感激。

php unicode matching multibyte non-latin
2个回答
2
投票

问题似乎与识别单词边界有关;该结构显然不“支持 Unicode”。这就是问题 php regex word border matches in utf-8 的答案似乎表明的内容。即使使用包含拉丁字母(如“é”)的文本,我也能够重现该问题。当我设置时,问题似乎消失了(即阿拉伯单词被正确识别)



$badwords = file_get_contents("badwords.txt");
$badtemp = explode("\n", $badwords);
$badwords = array_unique($badtemp);
$hasBadword = 0;
$query = strtolower($query);

foreach ($badwords as $key => $val) {
    if (!empty($val)) {
        $val = trim($val);
        $regexp = "/\b" . $val . "\b/i";
        if (preg_match($regexp, $query))
            $badFlag = 1;

        if ($badFlag == 1) {
           // Bad word detected die...
        }
    }
}

并修改正则表达式如下:

$badwords = file_get_contents("badwords.txt");
$badtemp = explode("\n", $badwords);
$badwords = array_unique($badtemp);
$hasBadword = 0;
$query = strtolower($query);

foreach ($badwords as $key => $val) {
    if (!empty($val)) {
        $val = trim($val);
        $regexp = "/\b" . $val . "\b/i";
        if (preg_match($regexp, $query))
            $badFlag = 1;

        if ($badFlag == 1) {
           // Bad word detected die...
        }
    }
}

0
投票

PHP 中的某些字符串函数不能用于 UTF-8 字符串,据说他们将在版本 6 中修复它,但现在您需要小心处理字符串。

看起来

$wstart = '(^|[^\p{L}])';
$wend = '([^\p{L}]|$)';
就是其中之一,你需要使用
$regexp = "/" . $wstart . $val . $wend . "/iu";
。如果这不能解决问题,您需要通读代码并找到处理
strtolower()
mb_strtolower($query, 'UTF-8')
的每个点,并检查 UTF-8 错误的文档。

据我所知,

$query
对于UTF-8字符串来说是可以的,但是默认情况下会禁用一些功能以提高性能。我认为您不需要其中任何一个。

另请仔细检查

badwords.txt
是否为 UTF-8 文件,并且
preg_match()
包含有效的 UTF-8 字符串(如果它来自浏览器,则使用
badwords.txt
标签进行设置)。

如果您尝试调试 UTF-8 文本,请记住大多数 Web 浏览器不会默认使用 UTF-8 文本编码,因此您打印出来用于调试的任何 PHP 变量都不会被浏览器正确显示,除非您选择 UTF -8(在我的浏览器中,带有

$query
)。

您不需要使用

<meta>
或任何其他转换 API,它们中的大多数都会简单地将所有非拉丁字符替换为拉丁字符。显然不是你想要的。

© www.soinside.com 2019 - 2024. All rights reserved.