Regex - сопоставлять (только) слова со смешанными символами

Я пишу свой фильтр против спама / недоброжелателей, и мне нужно, если это возможно,

сопоставлять (определять) только слова, образованные смешанными символами, такими как: fr1&nd$, а не друзья

это возможно с регулярным выражением!?

с уважением!

4 ответа

Решение

Конечно, это возможно с регулярным выражением! Вы не просите соответствовать вложенным скобкам!:П

Но да, именно для этого были созданы регулярные выражения. Пример:

/\S*[^\w\s]+\S*/

Это будет соответствовать всем следующим:

@ss
as$
a$s
@$s
a$$
@s$
@$$

Это не будет соответствовать этому:

ass

Который я верю, что вы хотите. Как это устроено:

\S* соответствует 0 или более непробельных символов. [^\w\s]+ соответствует только символам (это будет соответствовать всему, что не является словом или пробелом), и соответствует 1 или более из них (поэтому требуется символьный символ). Затем \S* снова соответствует 0 или более непробельных символов (символов и букв).

Если мне будет позволено предложить лучшую стратегию, в Perl вы можете хранить регулярные выражения в переменной. Я не знаю, можете ли вы сделать это в PHP, но если вы можете, вы можете создать список переменных, например:

$a = /[aA@]/ # regex that matches all a-like symbols
$b = /[bB]/
$c = /[cC(]/
# etc...

Или же:

$regex = array( 'a' => /[aA@]/, 'b' => /[bB]/, 'c' => /[cC(]/, ... );

Таким образом, вы можете сопоставить "друга" во всех его перестановках с:

/$f$r$i$e$n$d/

Или же:

/$regex['f']$regex['r']$regex['i']$regex['e']$regex['n']$regex['d']/

Конечно, второй выглядит излишне многословным, но это PHP для вас. Я думаю, что второе, вероятно, является лучшим решением, так как оно хранит их все в хэше, а не как отдельные переменные, но я признаю, что регулярное выражение, которое он создает, немного уродливо.

Не проверял это полностью, но это должно сделать это:

(\w+)*(?<=[^A-Za-z ])

Вы можете создать несколько регулярных выражений, например:

\p{L}+[\d\p{S}]+\S*

Это будет соответствовать любой последовательности из одной или нескольких букв (\p{L}+, см. настройки символов Юникода), одну или несколько цифр или символов ([\d\p{S}]+) и любые последующие непробельные символы \S*,

$str = 'fr1&nd$ and not friends';
preg_match('/\p{L}+[\d\p{S}]+\S*/', $str, $match);
var_dump($match);

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

Я предполагаю, что у вас будет куча правил регулярных выражений для обнаружения плохих слов, например:

Чтобы обнаружить fr1&nd$, друзей, fr**nd*, вы можете использовать регулярные выражения, такие как:

/fr[1iI*][&eE]nd[s$Sz]/

Делая что-то подобное для каждого правила, вы найдете все варианты возможных символов в скобках. Подберите руководство по регулярным выражениям для получения дополнительной информации.

(Я предполагаю, что для фильтра плохих слов вы хотели бы friend так же как frie**Вы можете замаскировать плохое слово, а также все возможные перестановки)

Другие вопросы по тегам