3

Lets say I have an array of bad words:

$badwords = array("one", "two", "three");

And random string:

$string = "some variable text";

How to create this cycle:

if (one or more items from the $badwords array is found in $string)
echo "sorry bad word found";
else
echo "string contains no bad words";

Example:
if $string = "one fine day" or "one fine day two of us did something", user should see sorry bad word found message.
If $string = "fine day", user should see string contains no bad words message.

As I know, you can't preg_match from array. Any advices?

Taz
  • 3,718
  • 2
  • 37
  • 59
DadaB
  • 762
  • 4
  • 12
  • 29
  • $string is allways a random string, Its a search query to be more specific. So if visitor enters query containing bad words, he should see no results, else.. Well you got the point? :) – DadaB Apr 27 '12 at 22:00
  • And **yes you can `preg_match`** an array, you just need to implode it first. Check my answer given. – JT Smith Apr 28 '12 at 00:29

4 Answers4

7

How about this:

$badWords = array('one', 'two', 'three');
$stringToCheck = 'some stringy thing';
// $stringToCheck = 'one stringy thing';

$noBadWordsFound = true;
foreach ($badWords as $badWord) {
  if (preg_match("/\b$badWord\b/", $stringToCheck)) {
    $noBadWordsFound = false;
    break;
  }
}
if ($noBadWordsFound) { ... } else { ... }
raina77ow
  • 103,633
  • 15
  • 192
  • 229
  • I used your code for Arabic strings and it worked fine. next day i tried to run the code without any modification but gives me wrong result. the problem is in the preg_match function. any help please? – Fshamri Sep 20 '15 at 20:54
5

Why do you want to use preg_match() here?
What about this:

foreach($badwords as $badword)
{
  if (strpos($string, $badword) !== false)
    echo "sorry bad word found";
  else
    echo "string contains no bad words";
}

If you need preg_match() for some reasons, you can generate regex pattern dynamically. Something like this:

$pattern = '/(' . implode('|', $badwords) . ')/'; // $pattern = /(one|two|three)/
$result = preg_match($pattern, $string);

HTH

yuvin
  • 363
  • 1
  • 12
2

If you want to check each word by exploding the string into words, you can use this:

$badwordsfound = count(array_filter(
    explode(" ",$string),
    function ($element) use ($badwords) {
        if(in_array($element,$badwords)) 
            return true; 
        }
    })) > 0;

if($badwordsfound){
   echo "Bad words found";
}else{
   echo "String clean";
}

Now, something better came to my mind, how about replacing all the bad words from the array and check if the string stays the same?

$badwords_replace = array_fill(0,count($badwords),"");
$string_clean = str_replace($badwords,$badwords_replace,$string);
if($string_clean == $string) {
    echo "no bad words found";
}else{
    echo "bad words found";
}
Taha Paksu
  • 15,371
  • 2
  • 44
  • 78
1

Here is the bad word filter I use and it works great:

private static $bad_name = array("word1", "word2", "word3");

// This will check for exact words only. so "ass" will be found and flagged 
// but not "classic"

$badFound = preg_match("/\b(" . implode(self::$bad_name,"|") . ")\b/i", $name_in);

Then I have another variable with select strings to match:

// This will match "ass" as well as "classic" and flag it

private static $forbidden_name = array("word1", "word2", "word3");

$forbiddenFound = preg_match("/(" . implode(self::$forbidden_name,"|") . ")/i", $name_in);

Then I run an if on it:

if ($badFound) {
   return FALSE;
} elseif ($forbiddenFound) {
   return FALSE;
} else {
   return TRUE;
}

Hope this helps. Ask if you need me to clarify anything.

JT Smith
  • 741
  • 4
  • 12