2011-12-25 71 views
0

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

我该如何去匹配拉丁和非拉丁关键词。

的badwords.txt文件包括每行一个字作为在本例中用于匹配

bad 

nasty 

racist 

سفالة 

وساخة 

جنس 

代码:

$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... 
     } 
    } 
} 

我读过的iconv,多字节函数(MBSTRING),并使用操作员/你可能会对此有所帮助,我尝试了一些东西,但似乎没有把它做好。任何帮助,将不胜感激解决这个问题,并让它匹配拉丁和非拉丁关键字。

回答

2

该问题似乎与识别单词边界有关; \ b结构显然不是“Unicode意识”。这就是php regex word boundary matching in utf-8问题的答案似乎表明的意思。当使用\ b时,即使使用包含拉丁字母的文本(如“é”),我也能够重现问题。而问题似乎消失(即阿拉伯语词汇得到正确识别)当我设置

$wstart = '(^|[^\p{L}])'; 
$wend = '([^\p{L}]|$)'; 

和修改正则表达式如下:

$regexp = "/" . $wstart . $val . $wend . "/iu"; 
+0

谢谢Jukka,这正是我所需要的,它终于有效。我不会认为这个问题会成为事实。在我测试各种建议时,边界正则表达式实际上始终保持不变。非常感谢。 – Yallaa 2011-12-26 22:29:12

0

PHP中的一些字符串函数不能用于UTF-8字符串,他们应该会在第6版中修复它,但现在你需要小心你如何处理字符串。

看起来像strtolower()就是其中之一,您需要使用mb_strtolower($query, 'UTF-8')。如果这不能解决问题,您需要仔细阅读代码并找到处理$querybadwords.txt的每个点,并检查文档中的UTF-8错误。

据我所知,preg_match()与UTF-8字符串一致,但有一些功能在默认情况下被禁用以提高性能。我不认为你需要他们中的任何一个。

也请仔细检查badwords.txt是UTF-8文件和$query包含有效的UTF-8字符串(如果它是来自浏览器的,你有<meta>标签设置)。

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

您不应该需要使用iconv或任何其他转换API,它们中的大多数将简单地将所有非拉丁字符替换为拉丁字符。显然不是你想要的。

+1

谢谢ABHI的响应。该文件确实使用UTF-8保存,并且查询来自使用meta charset = utf-8“的UTF-8编码页面。我之前使用过mb_strtolower()和mb_ereg_match(),它们仍然与英文关键字匹配,但而不是阿拉伯语,这与浏览器的默认语言无关,只是与坏字中存在的查询关键字相匹配。txt文件,然后进行进一步处理,所有演示文稿页面都是UTF-8编码页面。任何进一步的想法将不胜感激。谢谢 – Yallaa 2011-12-25 23:27:36