2011-12-25 22 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