0

ローカルのUTF-8エンコードファイルに保存されているキーワードのリストを使用する不適切な単語フィルターがあります。このファイルには、ラテン語と非ラテン語の両方の文字(主に英語とアラビア語)が含まれています。ラテン語のキーワードではすべてが期待どおりに機能しますが、変数に非ラテン語の文字が含まれている場合、マッチングではこれらの既存のキーワードが認識されないようです。

ラテン語と非ラテン語の両方のキーワードを一致させるにはどうすればよいですか。

この例のように、badwords.txtファイルには1行に1つの単語が含まれています

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)を読み、演算子/ uを使用するとこれが役立つ場合があります。いくつか試してみましたが、正しく機能しないようです。これを解決し、ラテン語と非ラテン語の両方のキーワードに一致させるために、どんな助けでも大歓迎です。

4

2 に答える 2

2

問題は、単語の境界の認識に関連しているようです。\b構文は明らかに「Unicode対応」ではありません。これは、utf-8でのphpregex単語境界マッチングの質問に対する回答が示唆しているようです。\ bを使用すると、「é」のようなラテン文字を含むテキストでも問題を再現できました。そして、私が設定すると、問題は消えるように見えます(つまり、アラビア語の単語が正しく認識されます)

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

正規表現を次のように変更します。

$regexp = "/" . $wstart . $val . $wend . "/iu";
于 2011-12-26T17:05:54.020 に答える
0

PHPの一部の文字列関数はUTF-8文字列では使用できません。バージョン6で修正される予定ですが、今のところ、文字列の操作には注意する必要があります。

そのうちの1つであるように見えstrtolower()ますが、を使用する必要がありますmb_strtolower($query, 'UTF-8')。それでも問題が解決しない場合は、コードを読み、処理するすべてのポイントを見つける$querybadwords.txt、ドキュメントでUTF-8のバグを確認する必要があります。

私の知る限り、preg_match()UTF-8文字列は問題ありませんが、パフォーマンスを向上させるためにデフォルトで無効になっている機能がいくつかあります。私はあなたがそれらのどれも必要としないと思います。

badwords.txtまた、UTF-8ファイルであり、有効なUTF-8文字列が含まれていることを再確認してください$query(ブラウザからのものである場合は、<meta>タグを設定します)。

UTF-8テキストをデバッグしようとしている場合、ほとんどのWebブラウザはデフォルトでUTF-8テキストエンコーディングに設定されていないため、UTF-を選択しない限り、デバッグ用に出力するPHP変数はブラウザによって正しく表示されません。 8(私のブラウザではView -> Encoding -> Unicode)。

iconvまたは他の変換APIを使用する必要はありません。それらのほとんどは、ラテン文字以外のすべての文字をラテン文字に置き換えるだけです。明らかにあなたが望むものではありません。

于 2011-12-25T22:59:56.843 に答える