badWords array and preg_match

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
User avatar
gd77
Forum Newbie
Posts: 20
Joined: Sat Feb 26, 2011 6:11 pm

badWords array and preg_match

Post by gd77 »

Hello:
consider the following:
tye1:
$badwords=array('word1','word2');
type2:
$badwords="word1|word2";

$txt="some text...";

eregi is deprecate we can use preg_match or preg_grep well both of them not working with me.
if you can help, I ll be thankfull.
Thanks.
User avatar
AbraCadaver
DevNet Master
Posts: 2572
Joined: Mon Feb 24, 2003 10:12 am
Location: The Republic of Texas
Contact:

Re: badWords array and preg_match

Post by AbraCadaver »

Can't use an array for the pattern, it needs to be a string. You need delimiters, and maybe the i modifier for case insensitivity:

Code: Select all

$badwords = '/word1|word2/i';
And you might want a word boundary so it won't match passive etc.

Code: Select all

$badwords = '/\bword1|word2\b/i';
If you want to use an array for some reason then implode() it with |.
mysql_function(): WARNING: This extension is deprecated as of PHP 5.5.0, and will be removed in the future. Instead, the MySQLi or PDO_MySQLextension should be used. See also MySQL: choosing an API guide and related FAQ for more information.
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Re: badWords array and preg_match

Post by John Cartwright »

Don't forget to use preg_quote() on each word to escape any harmful characters.
User avatar
gd77
Forum Newbie
Posts: 20
Joined: Sat Feb 26, 2011 6:11 pm

Re: badWords array and preg_match

Post by gd77 »

so Basically this should work?
$txt="hi how r u jizz, yed";

$badWords='jizz|yed';

$badWords1 = preg_quote($badWords);
if(preg_match('/^\b'.$badWords1.'\b+$/i', $txt)){
echo "worked<br>";
}

getting Warning: Compilation failed: nothing to repeat at offset.
User avatar
AbraCadaver
DevNet Master
Posts: 2572
Joined: Mon Feb 24, 2003 10:12 am
Location: The Republic of Texas
Contact:

Re: badWords array and preg_match

Post by AbraCadaver »

I gave you the pattern and you have arbitrarily added things to it which is why it doesn't work. Don't use preg_quote(). You only need this when you are using raw data. It will escape needed characters in your pattern like | so don't use it.

Probably:

Code: Select all

preg_match('/\b('.$badWords1.')\b/i', $txt);
mysql_function(): WARNING: This extension is deprecated as of PHP 5.5.0, and will be removed in the future. Instead, the MySQLi or PDO_MySQLextension should be used. See also MySQL: choosing an API guide and related FAQ for more information.
User avatar
Jonah Bron
DevNet Master
Posts: 2764
Joined: Thu Mar 15, 2007 6:28 pm
Location: Redding, California

Re: badWords array and preg_match

Post by Jonah Bron »

How about this?

Code: Select all

$isTainted = false;
for ($words as $word) {
    if (stripos($text, $word) !== false) {
        $isTainted = true;
        break;
    }
}
No regular expression matching, and stops as soon as it gets a positive. Not sure if it's really faster though, I'd have to do a performance test. It's advantage is probably variable.
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Re: badWords array and preg_match

Post by John Cartwright »

AbraCadaver wrote:I gave you the pattern and you have arbitrarily added things to it which is why it doesn't work. Don't use preg_quote(). You only need this when you are using raw data. It will escape needed characters in your pattern like | so don't use it.

Probably:

Code: Select all

preg_match('/\b('.$badWords1.')\b/i', $txt);
Why wouldn't you want to use preg_quote()? What if a word was added in the future that may have a character that will break the pattern?

And lastly, you want to apply preg_quote() to each individual word, not the combined words.

I.e.,

Code: Select all

$badWords = array('jizz', 'yed');

$badWordsPreg = implode('|', array_map('preg_quote', $badWords));

if(preg_match('/\b'. $badWordsPreg .'\b+$/i', $txt)){
   echo "worked<br>";
}
Notice I removed the ^ in the pattern, since this would only match if the bad words appeared at the beginning of the pattern.
User avatar
Jonah Bron
DevNet Master
Posts: 2764
Joined: Thu Mar 15, 2007 6:28 pm
Location: Redding, California

Re: badWords array and preg_match

Post by Jonah Bron »

Or if you go the regex route, it'd be better to put the words into an array, preg_quote(), then implode().

Code: Select all

$words = array('word1', 'word2');
$words = array_map('preg_quote', $words);
$words = implode('|', $words);
// match...
Edit: oops, you beat me to it John :drunk:
User avatar
gd77
Forum Newbie
Posts: 20
Joined: Sat Feb 26, 2011 6:11 pm

Re: badWords array and preg_match

Post by gd77 »

Thanks Jonah, worked great, array_map was the missing piece :).
Thanks to you all too :)
Post Reply