У меня есть фильтр, который фильтрует плохие слова, такие как «задница», «fuck» и т. Д. Теперь я пытаюсь обрабатывать эксплойты типа «f * ck», «sh / t».
Одна вещь, которую я мог бы сделать, – это сопоставление каждого слова со словарем плохого слова с такими эксплоитами. Но это довольно статический и не очень хороший подход.
Еще одна вещь, которую я могу сделать, – использовать левенштейновское расстояние. Слова с левенштейном distance = 1 должны быть заблокированы. Но этот подход также склонен давать ложные результаты.
if(!ctype_alpha($text)&& levenshtein('shit', $text)===1) { //match }
Я ищу способ использования регулярного выражения. Может быть, я могу комбинировать расстояние levenshtein с regex
, но я не мог понять это.
Любое предложение очень важно.
Как указано в комментариях, это трудно понять. Этот фрагмент, далекий от совершенства, проверяет наличие совпадений, в которых буквы заменяются одинаковым количеством других символов.
Это может дать вам общее представление о том, как вы можете это решить, хотя требуется гораздо больше логики, если вы хотите сделать его более умным. Этот фильтр, например, не будет фильтровать «fukk», «f ck», «f ** ck», «fck», «.fuck» (с ведущей точкой) или «fück», хотя он, вероятно, отфильтровывает «+ +++ ', чтобы заменить его «звуковым сигналом». Но он также фильтрует «f * ck», «f ** k», «f * cking» и «sh1t», поэтому он может ухудшиться. 🙂
Легкий способ сделать это лучше – разбить строку более разумно, поэтому знаки препинания не приклеены к тому слову, к которому они примыкают. Еще одно улучшение может заключаться в том, чтобы удалить все неалфавитные символы из каждого слова и проверить, находятся ли остальные буквы в одном и том же порядке в одном слове. Таким образом, «f \ / ck» также будет соответствовать «fuck». Во всяком случае, пусть ваше воображение будет диким, но будьте осторожны с ложными срабатываниями. И поверьте мне, что «они» всегда найдут способ выразить себя таким образом, чтобы обходить ваш фильтр.
<?php $badwords = array('shit', 'fuck'); $text = 'Man, I shot this f*ck, sh/t! fucking fucker sh!t fukk. I love this. ;)'; $words = explode(' ', $text); // Loop through all words. foreach ($words as $word) { $naughty = false; // Match each bad word against each word. foreach ($badwords as $badword) { // If the word is shorter than the bad word, it's okay. // It may be bigger. I've done this mainly, because in the example given, // 'f*ck,' will contain the trailing comma. This could be easily solved by // splitting the string a bit smarter. But the added benefit, is that it also // matches derivatives, like 'f*cking' or 'f*cker', although that could also // result in more false positives. if (strlen($word) >= strlen($badword)) { $wordOk = false; // Check each character in the string. for ($i = 0; $i < strlen($badword); $i++) { // If the letters don't match, and the letter is an actual // letter, this is not a bad word. if ($badword[$i] !== $word[$i] && ctype_alpha($word[$i])) { $wordOk = true; break; } } // If the word is not okay, break the loop. if (!$wordOk) { $naughty = true; break; } } } // Echo the sensored word. echo $naughty ? 'beep ' : ($word . ' '); }