views:

58

answers:

5

I got a contact form, I need to filter some words.

I'm doing it as following:

$array = array('lorem', 'ipsum', 'ip.sum');
for($i = 0; $i < count($array); $i++)
        {
            if( preg_match("/".$array[$i]."/", (string) $field) )
            {
                return false;
            }
        }

I'm not a regex master, but it should be working for words like: lorem or ipsum. But it is not.

BTW. Any suggestions how to catch mispelled words, ex. i.psum, l.o.rem?

Update
Of course, I have no empty pattern, I just forgot to paste it.

Update 2
I've decided to got the way suggested by Daniel Vandersluis. Abnyway, I'm not able to make it working.

$field = "ipsum lorem"; // This value comes from textarea
$array = array('ipsum', 'lorem', 'ip.sum');
foreach($array as $term):
    if(preg_match('/'.preg_quote($term).'/', $field)) {
        return false;
    }
endforeach;

Any ideas?

A: 

Change

if( preg_match("//", (string) $field) )

to

if( preg_match("/$array[$i]/", (string) $field) )
codaddict
Thanks for pointing this out, it was a typo only ;)
Frank Watler von Hohenstein
+2  A: 

You don't need regexes for simple word filtering.

function is_offensive($to_be_checked){
   $offensive = array('lorem', 'ipsum', 'ip.sum');
   foreach($offensive as $word){
      if(stristr($to_be_checked, $word) !== FALSE){
          return FALSE;
      }
   }
}

Usage:

$field = $_POST['field'];
if(is_offensive($field)){
   echo 'Do not curse on me! I did not crash your computer!';
}
else{
    //make the visitor happy
}
Lekensteyn
+3  A: 

If I understand correctly, and you want to see if any of the words in your array are in your field, you can do something like this:

function check_for_disallowed_words($text, $words)
{
  // $text is the text being checked, $words is an array of disallowed words
  foreach($words as $word)
  {
    if (preg_match('/' . preg_quote($word) . '/', $text))
    {
      return false;
    }
  }

  return true;
}

$array = array('lorem', 'ipsum', 'ip.sum');
$valid = check_for_disallowed_words($field, $array);

In your example, you weren't defining any pattern to be used. preg_quote will take a string and make it ready to use in a regular expression (because, for example, the dot in ip.sum actually has special meaning in a regular expression so it needs to be escaped if you want to search for a literal dot).

As an aside, if you'd like to learn more about regular expressions, take a look at the tutorial on regular-expressions.info, it is very in depth.

Daniel Vandersluis
Daniel, could you be so nice and take a look at edited quesiton? Am I idiot or I'm blind? :)
Frank Watler von Hohenstein
@Frank what's not working?
Daniel Vandersluis
@Frank would my assumption that you didn't put the code into a function be correct? You can't have a `return` statement outside of a function. I updated my code with an example.
Daniel Vandersluis
@Daniel - No. I am an idiot. I was sending WRONG field content to this function. Anyway, it's working perfectly! How's about catching words similar to: ip.sum, ips.um?
Frank Watler von Hohenstein
@Frank there's no easy way to cover all possibilities. You could try stripping out non-word characters using that to compare to (so `ip.sum` -> `ipsum` -> matches a disallowed word)
Daniel Vandersluis
Thanks, everything is working perfectly. For covering all possibilities I just created an array with some variations. Thanks for your support.
Frank Watler von Hohenstein
+1  A: 

I translated your question for me like this: how can I replace words from a variable via set of regular expressions.

You can try this:

 $array = array('lorem', 'ipsum', 'ip.sum', '');

 $field = preg_replace("/(" . implode(")|(", $array) . ")/i", "--FILTERED-OUT--", (string) $field));

It constructs the final regular expression from elements of $array. So that you can specify a word as regular expression (ip.sum ~ ip[whatever character]sum). Flag i is used for case-insensitive search.

MartyIX
+1 for efficiency, even though the search fields were not quoted (so there's potential to have an invalid regex)...
ircmaxell
I suppose that in $array are regexes. Otherwise `preg_quote` can by applied to all elements of array via `array_map` (I guess).
MartyIX
A: 

Another variant, maybe that's of some use (you didn't specify the problem very thoroughly):

Edited according to user's comment:

 // comparison function
 function check_field_in($field, $phrases)
{
 foreach($phrases as $phrase) {
    $match_text = quotemeta($phrase);            // if this works, 
    if( preg_match("/^$match_text$/", $field) )  // this part can be optimized
       return false;                             
 }
 return true;
}

// main program goes here
 $textarea = 'lorem ipsum  i.psum l.o.rem';

 foreach(preg_split('/\s+/', $textarea) as $field) {
    if( check_field_in( $field, array('lorem','ipsum') ) == true )
       echo "$field OK\n";
    else
       echo "$field NOT OK\n";
 }

This will print:

lorem NOT OK
ipsum NOT OK
i.psum OK
l.o.rem OK

Regards

rbo

rubber boots
@rbo - We're close to what I want but I need to return false is textarea string contain any key from array.
Frank Watler von Hohenstein
@Frank: exchange **return true** with **return false** and you're done!
rubber boots