2015-03-21 2 views
0

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

Warning: preg_match() [function.preg-match]: Unknown modifier ‘/’

Вот код:

if (isset($_POST['text'])) { 

// Words not allowed 
$disallowedWords = array(
'bad1', 
'bad2', 
); 
// Search for disallowed words. 
// The Regex used here should e.g. 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|[a-z 
A-Z]{2}))(\:[0-9]+)*(/($|[a-zA-Z0-9\.\,\?\'\\\+&%\$#\=~_\-]+))*/'; 

// Search for URLs 
if (preg_match($urlRegex, $entry)) { 
die("URLs are not allowed..."); 
} 

} 
+0

Почему именно так. Вы можете проверить совпадения с помощью http://php.net/strpos. Что касается вашего вопроса, регулярное выражение терпит неудачу, потому что вам требуется свободное пространство с обеих сторон. Вы хотите '\ s *', но тогда 'notbadword' также будет соответствовать ... – chris85

+0

У вас есть две проблемы, сначала пропустили сообщение об ошибке. Это от ваших разделителей. Проверьте регулярное выражение URL-проверки. – chris85

+0

Я бы использовал это регулярное выражение:/\ b $ word \ b/i, потому что он будет соответствовать плохим словам в конце и в начале строки тоже, а не только между словами ... – sinisake

ответ

0

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

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

Вы также можете проверить свои регулярные выражения here. Используйте /\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, вы должны бежать / с \, как это: \/

0

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

<?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]))); 
    } 
} 

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

+0

Я ошибаюсь, думая, что это тоже будет соответствовать 'notbad1' в строке? – jvitasek

+0

@jvitasek И ОП сказал, где это не должно произойти? – arkascha

+0

@jvitasek Да, но это система OPs, а не ваша. Вы не знаете, чего хочет OP. По крайней мере, вы не должны предполагать, что вы это делаете. Общая ошибка ... – arkascha

0

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

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

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

Как ваш фильтр «плохих слов»:

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