preg_match переменная ключевого слова для списка ключевых слов латинских и нелатинских символов в локальном файле в кодировке UTF-8 - PullRequest
0 голосов
/ 26 декабря 2011

У меня есть фильтр плохих слов, который использует список ключевых слов, сохраненный в локальном файле в кодировке UTF-8. Этот файл включает как латинские, так и нелатинские символы (в основном английский и арабский). Все работает, как и ожидалось, с латинскими ключевыми словами, но когда переменная включает в себя нелатинские символы, сопоставление, по-видимому, не распознает эти существующие ключевые слова.

Как мне найти соответствия как латинским, так и нелатинским ключевым словам.

Файл badwords.txt содержит одно слово в строке, как в этом примере </p> <pre><code>bad nasty racist سفالة وساخة جنس

Код, используемый для сопоставления: <pre></p> <pre><code>$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 могут помочь с этим, и я попробовал несколько вещей, но, похоже, не понял правильно. Любая помощь будет очень признательна в решении этой проблемы и при ее совпадении с латинскими и нелатинскими ключевыми словами.

Ответы [ 2 ]

2 голосов
/ 26 декабря 2011

Проблема, похоже, связана с распознаванием границ слов; конструкция \ b, по-видимому, не «поддерживает Unicode». Это то, что, по-видимому, предлагают ответы на вопрос сопоставление границ слова php regex в utf-8 . Мне удалось воспроизвести проблему даже с текстом, содержащим латинские буквы, такие как «é», когда использовался \ b. И проблема, кажется, исчезает (то есть, арабские слова распознаются правильно), когда я устанавливаю

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

и измените регулярное выражение следующим образом:

$regexp = "/" . $wstart . $val . $wend . "/iu";
0 голосов
/ 26 декабря 2011

Некоторые строковые функции в PHP нельзя использовать со строками UTF-8, они предположительно исправят это в версии 6, но сейчас вам нужно быть осторожным с тем, что вы делаете со строкой.

Похоже, strtolower() является одним из них, вам нужно использовать mb_strtolower($query, 'UTF-8'). Если это не помогает, вам нужно прочитать код и найти каждую точку, где вы обрабатываете $query или badwords.txt, и проверить документацию на ошибки UTF-8.

Насколько я знаю, preg_match() подходит для строк UTF-8, но некоторые функции по умолчанию отключены для повышения производительности. Я не думаю, что вам нужен ни один из них.

Пожалуйста, дважды проверьте, что badwords.txt является файлом UTF-8 и что $query содержит допустимую строку UTF-8 (если она поступает из браузера, вы устанавливаете ее с тегом <meta>).

Если вы пытаетесь отлаживать текст UTF-8, помните, что большинство веб-браузеров не используют кодировку текста UTF-8 по умолчанию, поэтому любая переменная PHP, которую вы выводите для отладки, не будет правильно отображаться браузером, если вы не выберите UTF-8 (в моем браузере, с помощью View -> Encoding -> Unicode).

Вам не нужно использовать iconv или любой другой API преобразования, большинство из них просто заменит все нелатинские символы латинскими. Очевидно, не то, что вы хотите.

...