| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > PHP: Тексты > Фильтр слов |
| Автор: Gold Dragon 30.1.2006, 11:07 |
| Допустим есть гостевая книга. Сообщения оставляются без предварительной модерации. Есть список слов (мат и т.п.) которые нужно находить в сообщении и заменять Вопрос: - как грамотнее организовать проверку и замену? И главное, какие функции быстреке будут работать? |
| Автор: Mal Hack 30.1.2006, 13:28 |
| Зависит от кол-ва слов и сложности правил... В принципе и preg-replace() - 1 раз можно прогнать. |
| Автор: AztEK 30.1.2006, 14:17 |
| А в идеале ещё и заменять слова, где скажем вместо русских букв используются латинские со схожим написанием. Тут, наверное, стоит все схожие символы ложить в массив и прегать по массиву. Правда не знаю насчёт скорости... |
| Автор: Gold Dragon 30.1.2006, 14:25 | ||
| Mal Hack почитал документацию и не совсем понял как это использовать вот например нужно в сообщении делать следующие замещения - aaa на ббб - 1234 на 4321 - ёй на юй а код типа такого
так чтоли? |
| Автор: AntonioBanderaz 30.1.2006, 15:59 |
| Это вроде str_replace В преге регульки |
| Автор: BIG BROTHER 30.1.2006, 17:19 |
| быстрее всего будет работать str_replace (т.е. обычная замена без регулярных выражений) НО правильней ИМХО делать так: в базе хранить корни слов - матов и смотреть в тексте именно эти корни. При нахождении корня заменять все слово в котором этот корень есть (т.е. от пробела до пробела) Но конечно на 100 уберечся нельзя например вот 2 слова: хорошо и xopoшo - визуально разницы вообще никакой а во втором слове буквы Х О и P- латинские икс, о и пе. да и после каждой буквы пробелов могут понаставить. В идеале конечно нужно все жестко модерировать и карать карой небесной нарушителей |
| Автор: AztEK 30.1.2006, 17:45 |
| BIG BROTHER корни - не дело. Будет резать безобидные слова типа "застрахуйте" |
| Автор: Mal Hack 30.1.2006, 18:29 | ||
Gold Dragon, если так, то:
Если 5 юзаешь, то str_ireplace |
| Автор: Gold Dragon 31.1.2006, 11:06 |
| BIG BROTHER наверное всё таки нужна регулярка, т.к. в базе лежат слова, а их надо проверять на наличие не алфавитного знака в начале и в конце. Например, слово "устой" не должно попасть в "плохие" слова по маске "сто", а ".сто" должно попасть. Как мне это сделать регулярными выражениями? Всем спасибо за пояснение к str_replace. Но как мне совместить это с базой? Или проще это хранить в переменной(Array) в каком-нибудь "языковом" файле? Если в базе, то наверное нужно будет всё равно в массив перегонять? BIG BROTHER само сабой, нет 100% защиты и нужна модерация, но я же не могу модерить постоянно online, вот и нужна какая-то элементарная защита пока модератор кушает пончики Добавлено @ 11:07 я юзаю 5-ку |
| Автор: BIG BROTHER 31.1.2006, 22:27 |
| Из базы не сложно перегнать в массив и прогнать str_replace и заменять на что-то вроде [censored] |
| Автор: Mal Hack 1.2.2006, 13:38 | ||
Gold Dragon
|
| Автор: PARROT 3.5.2006, 11:17 | ||||||
| Жизнь заставила сделать фильтр слов: В текстовом файле записаны слова: mate.txt
Делаю так:
Результат:
Получается, что он слово находит, но заменяет только первые три буквы. Как исправить? |
| Автор: Serkys 3.5.2006, 14:40 |
| PARROT, а откуда у тебя берётся $mas_com? |
| Автор: PARROT 3.5.2006, 14:46 |
| Из базы. В базу пишется текст сообщения, в котором могут содержаться такие слова. Потом при выводе нужно все это заменить. |
| Автор: Mal Hack 3.5.2006, 16:38 | ||
А если так:
|
| Автор: IZ@TOP 3.5.2006, 16:46 |
| Mal Hack, ммм... а в файле ж слова разделенные переносом строк... |
| Автор: Mal Hack 3.5.2006, 16:54 |
| Ах, ну да... Сорри, стормозил... Я бы тут альтернативной регуляркой прошолся бы. |
| Автор: IZ@TOP 3.5.2006, 16:59 |
| Mal Hack, да уж пробовали - regular expression too long Добавлено @ 16:59 Предпологаю что на сервере все прекрасно заработает. У меня во всяком случае проблем не возникло. |
| Автор: Mal Hack 3.5.2006, 17:06 |
| Надо бы вывести через print_r массив полученных слов и посмотреть. Вероятно он битый.. |
| Автор: PARROT 3.5.2006, 22:17 |
| Странно, действительно на сервере все заработало: http://pk.traktora.spb.ru/index.php?page=comment&idp=98 (Меня Денвер начинает раздражать..., второй баг уже) |
| Автор: Asbestos 30.6.2006, 07:20 |
| Леди и мужики, ситуация следующая: замену в строках произвожу str_ireplace, НО это отказывается воспринимать верхний регистр кириллицы хехе прошу прощения, забыл указать верную локаль |
| Автор: Gold Dragon 30.7.2006, 11:31 |
| Народ, ещё раз про замену... Что-то код с регуляркой не работает. $a = array ("aaa", "bbb", "ccc"); // что менять $b = array ("111", "222", "333"); //yf что менять $str = "aaa gaaa 1bbb bbb2 ccc qqq bbb! .aaa."; // где менять в итоге не должны поменяться только "gaaa" и "qqq" |
| Автор: Mal Hack 30.7.2006, 13:27 |
| А что ты хочешь сделать? Покажи код. |
| Автор: Gold Dragon 30.7.2006, 17:13 | ||
Mal Hack, я твой пытался запустить
Добавлено @ 17:14 а так как я в регах ничего не понимаю, так и не разобрался... там явно не хватает $b |
| Автор: Mal Hack 30.7.2006, 18:22 |
| А тут ты так не сделаешь. Тут надо через preg_replace_callback |
| Автор: Gold Dragon 30.7.2006, 18:39 |
| Mal Hack, ну тебе виднее, а через preg_replace_callback как ? просто через str_replace работает не так. он заменяет внутри слова |
| Автор: Mal Hack 30.7.2006, 21:34 | ||
Gold Dragon, поверь, я давно понял почему тебя str_replace не устраивает
|
| Автор: Gold Dragon 31.7.2006, 06:21 | ||||||
| совсем запутался нужно это
Mal Hack, зачем мне проверять слова на которые я меняю, ведь это мои слова замены, а не пользовательские? зы вот тестовая строка
|
| Автор: GiV 31.7.2006, 10:49 | ||
Должно было работать и без функции replace ($str = preg_replace("/([^a-z])" . $a[ $i ] . "([^a-z])/is", "\\1" . $b[ $i ] . "\\2", $str);), соединяющей куски, но на двух серверах странное поведение было. |
| Автор: Mal Hack 31.7.2006, 14:35 | ||
| Плохое решение. ЛУчше 1 раз пройтись большой регуляркой, чем много маленькими. Хотя и не всегда. Да и замудренно как-то это. Плюс, модификатор e сильно кушает память и может вызвать неприятности. Плюс, помним, что ьез установки локали RegEX не будет работать с кирилицей в паттерне.
|
| Автор: GiV 31.7.2006, 16:05 | ||
не всегда, хотя в данном случае правда Ваша. preg_replace с модификатором e работает медленне replace_callback + мы всегда будем проходить все n итерации (n-количество элементов в массиве для замены), что в худшем случае (ни одного вхождения искомого ключа в строку) все n раз заставит сработать preg_replace в холостую. В то время как большой прег выполнится только ОДИН раз, там выигрыши получаются от 2-х мс... И [\s.-=;] все же не все элементы включены (таб, запятая, восклицательный знак, двоеточие и т.д.), класс [^А-Яа-яA-Za-z] все же лучше. P.S. при достижении 100 с меня +. |
| Автор: Gold Dragon 31.7.2006, 17:12 |
| Наверное я слишком многое хочу Mal Hack, не все условия выполняются: замена происходит только если в начале стоит цифра, пробелы или точки, остальные не меняются... Т.е. ещё нужны условия: граничит с восклицательным знаком, когда слово идёт сначала, когда заканчивается на цифру (или скорее всего не на букву) |
| Автор: Mal Hack 31.7.2006, 18:58 | ||||||
Причем далеко не всегда. И сильно зависит от многих факторов. В свое время пришлось на этом деле @ схомячить.
Использование модификатора "e" очень частая ошибка многих пхпшников, которые наивно думают, что чем код короче, тем он быстрее "e"незаменим, когда надо в заменяющую функцию передать НЕСКОЛЬКО параметров, часть из которых не из карманов. При работе с BB кодами e незаменим. Там уж никак.
Тут есть два момента. Первый - кирилица. Бывает глюит, надо локаль включать обязательно через set_locate(). Второй момент, все-таки помнтся мне, что был квантофикатор \b или \B, \W тут не подойдет. И еще. [^А-Яа-яA-Za-z] все-таки большое-колво символов, а перечислив спецсимволы, как это сделал я, мы по логике получим в паттерне меньшее число проверок при компиляции, т.е. как мне кажется, указать все нужные спецсиволы будет лучше. |
| Автор: GiV 31.7.2006, 19:30 | ||||
Границы слова. Они тоже зависят от локали, так как определение идет фактически на таких раздельных регулярках ^\w, \w$, \w\W, \W\w, а \w и \W включают различные наборы символов (коды символов не только до 128, но и больше)
Ну в детали внутренней работы PCRE не вникал, так что пытаться что-либо доказать не буду. Я там не был, врать не стану. Можно попробовать попрофилировать код разных регулярок на одном и том же тектовом наборе, хотя это все частные случаи. |
| Автор: Gold Dragon 24.4.2007, 12:33 | ||||||||
так.. вопрос опять всплыл, но сейчас чуть всё проще, нужно тупо заменять слова. Просто не хочу сильно вымудряться. В общем есть массив со словами
обработка простая
но как мне сделать чтоб слова сравнивались без учёта регистра, чтоб не писать
я пытался сделать
Что подскажите? |
| Автор: xolod 24.4.2007, 13:55 | ||
|
| Автор: Gold Dragon 24.4.2007, 15:57 |
| О как??? А я и не знал.... А синтаксис у неё такой же? |