Плохой фильтр регулярных выражений слов не работает

Я пытаюсь заставить фильтр плохих слов работать. До сих пор с приведенным ниже кодом фильтрация не происходит, если я нахожу неправильное слово «bad1», указанное в массиве ниже, и я получаю эту ошибку:

Предупреждение: preg_match () [function.preg-match]: Неизвестный модификатор '/'

Вот код:

if (isset($_POST['text'])) { // Words not allowed $disallowedWords = array( 'bad1', 'bad2', ); // Search for disallowed words. // The Regex used here should eg match 'are', but not match 'care' foreach ($disallowedWords as $word) { if (preg_match("/\s+$word\s+/i", $entry)) { die("The word '$word' is not allowed..."); } } // Variable contains a regex that will match URLs $urlRegex = '/(http|https|ftp)\://([a-zA-Z0-9\.\-]+(\:[a-zA-Z0- 9\.&%\$\-]+)*@)*((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9] {1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1 -9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0) \.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])|localhost |([a-zA-Z0-9\-]+\.)*[a-zA-Z0-9\-]+\. (com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[az AZ]{2}))(\:[0-9]+)*(/($|[a-zA-Z0-9\.\,\?\'\\\+&%\$#\=~_\-]+))*/'; // Search for URLs if (preg_match($urlRegex, $entry)) { die("URLs are not allowed..."); } } 

Это правильный способ совпадения слов. Используйте это регулярное выражение в вашем цикле foreach.

 preg_match("#\b" . $word . "\b#", $entry); 

Здесь вы также можете проверить свои регулярные выражения. Используйте /\bbad1\b/g .

Код в действии:

 <?php // delete the line below in your code $entry = "notbad1word bad1 bad notbad1."; $disallowedWords = array( 'bad1', 'bad2', ); foreach ($disallowedWords as $word) { // use $_POST['text'] instead of $entry preg_match("#\b". $word ."\b#", $entry, $matches); if(!empty($matches)) die("The word " . $word . " is not allowed."); } echo "All good."; 

Этот код не соответствует notbad1word или notbad2word (и т. Д.), Но соответствует только bad1 или bad2 .

Что касается вашего urlRegex, вам нужно убежать / с \ как это: \/

Вы используете / как разделительный символ, но не избегаете его «внутренних» случаев:

 $urlRegex = '/(http|https|ftp)\://whatever/'; // ^ Unknown modifier '/' 

Либо измените разделитель, либо избежите косой черты.

Что касается фильтра «плохих слов»:

  1. Он не сможет распознать слова в начале и в конце строки. Рассмотрите возможность использования \b (границы слова) вместо \s+ .
  2. Если какое-либо из плохих слов в вашем массиве имеет неэкранированный символ регулярного выражения, результаты могут быть неожиданными. Рассмотрим использование preg_quote для каждого слова из массива.
  3. n preg_match вызывает n слов не очень эффективно. Я бы рекомендовал разложить массив слов в одно регулярное выражение, например '/\b(word1|word2|word3)\b/i' .

Вы можете сделать это без медленного цикла:

 <?php $_POST['text'] = 'This sentence uses the nobad1 bad2 word!'; if (isset($_POST['text'])) { // Words not allowed $disallowedWords = array( 'bad1', 'bad2', ); $pattern = sprintf('/(\\s%s\\s)/i', implode('\\s|\\s',$disallowedWords)); $subject = ' '.$_POST['text'].' '; if (preg_match($pattern, $subject, $token)) { die(sprintf("The word '%s' is not allowed...\n", trim($token[1]))); } } 

Вы должны убедиться, что каталог слов не содержит символов / , ( или ) .