Php regex search array

preg_match array items in string?

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?

$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? 🙂

4 Answers 4

$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

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?

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

foreach($badwords as $badword)

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); 

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

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

I suggest splitting on something like ‘\b’, otherwise bad words will run wild when followed by comma or other separators. )

Yea, I realized that (clbuttic) and then wrote the second solution which I think is very practical to solve it. Thanks @JTSmith.

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); 
if ($badFound) < return FALSE; >elseif ($forbiddenFound) < return FALSE; >else

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

Читайте также:  Строки java поиск символа

Источник

search string with array of values with PHP

I am trying to search a list of files and only perform work on the files that have names that contain a few values in an array. I am hoping to not have to loop through the array each time I have a new filename.
ala-

$needle = array('blah', 'bleh'); foreach($file_list as $file) < foreach($needle as $need) if(strstr($file, $need) !== false) < // do something. >> 

I just need to know if one of the strings in the array is in the filename, not the location of the string. I would like to use something similar to strstr() but it does not allow an array to be used as the needle. i.e.-

if(strstr($haystack, array('blah', 'bleh'))) < // do something. >

I would prefer to stay away from regular expressions, it seems to be a sledge for a hammer’s job. any ideas?

actually is the problem that you don’t want to loop the entire array or that you can’t pass an array as a needle?

6 Answers 6

IMO it is fine to use regular expressions here:

$pattern = '/' . implode('|', array_map('preg_quote', $needle)) . '/i'; foreach($file_list as $file) < if(preg_match($pattern, $file)) < // do something >> 

Here is a more «creative» way to do it (but it uses internal loops and is very likely slower, as you actually loop several times over the array):

function cstrstr($haystack, $needle) < return strstr($haystack, $needle) !== false; >foreach($file_list as $file) < if(array_sum(array_map('cstrstr', array_pad(array($file), count($needle), $file), $needle))) < // do something >> 

But the advantages with the regex should be obvious: You have to create the pattern only once whereas in the «funny» solution you always have to create an array of length count($needle) for every $file .

why to use regex if it is possible to simply use strstr() or in_array() ? it will increase the complexity of algorithm.

Читайте также:  Python check if json is empty

@s3v3n: Yes you can loop and use strstr() and break when you found it. That is another solution. But in_array only works if the name of the file is equal to a word contained in the array. I understood the question in the way that the filename can contain words in the array.

You can use in_array(). Example:

@Patrick, could you provide an example of the file names you’re working with? It may be easier to apply a specific naming convention to your files in order to get in_array() to work correctly. If you’re goal is to not iterate through the array each time, in_array() is the best way to go.

@OV Web Solutions, it will generally be file extension based, but I may have to do other conventions in the future.

This will perform an action on all the files that contain all the needles inside their name

// Loop through files foreach($files as $file) < foreach($needles as $needle)< // if filename does not contain this needle if(strpos($file, $needle) === false) continue 2; // skip to next file >// this file matches criteria. do smth on this file > 

in_array may work just fine, however it would require exact matches in your needle array.

You could implode the array with some hash-string, and use the result with strstr or strpos — str variant returns the first occurrence, pos only the position of the first occurrence— Make sure to have a very unique string, with both an uncommon prefix and suffix. This is rather a quick and dirty approach, but it may just work in your situation.

EDIT I was just thinking, why don’t you want to use a loop? It’ll be much faster than concatenating all elements from an array. Your question if there is a function to find partial matches using a reference array: it’s not build-in, so you’d better use your own loop (or implement some function to do it, using a loop of course)

Источник

How do you perform a preg_match where the pattern is an array, in php?

I have an array full of patterns that I need matched. Any way to do that, other than a for() loop? Im trying to do it in the least CPU intensive way, since I will be doing dozens of these every minute. Real world example is, Im building a link status checker, which will check links to various online video sites, to ensure that the videos are still live. Each domain has several «dead keywords», if these are found in the html of a page, that means the file was deleted. These are stored in the array. I need to match the contents pf the array, against the html output of the page.

Читайте также:  Java gettime in milliseconds

7 Answers 7

First of all, if you literally are only doing dozens every minute, then I wouldn’t worry terribly about the performance in this case. These matches are pretty quick, and I don’t think you’re going to have a performance problem by iterating through your patterns array and calling preg_match separately like this:

$matches = false; foreach ($pattern_array as $pattern) < if (preg_match($pattern, $page)) < $matches = true; >> 

You can indeed combine all the patterns into one using the or operator like some people are suggesting, but don’t just slap them together with a | . This will break badly if any of your patterns contain the or operator.

I would recommend at least grouping your patterns using parenthesis like:

foreach ($patterns as $pattern) < $grouped_patterns[] = "(" . $pattern . ")"; >$master_pattern = implode($grouped_patterns, "|"); 

But. I’m not really sure if this ends up being faster. Something has to loop through them, whether it’s the preg_match or PHP. If I had to guess I’d guess that individual matches would be close to as fast and easier to read and maintain.

Lastly, if performance is what you’re looking for here, I think the most important thing to do is pull out the non regex matches into a simple «string contains» check. I would imagine that some of your checks must be simple string checks like looking to see if «This Site is Closed» is on the page.

foreach ($strings_to_match as $string_to_match) < if (strpos($page, $string_to_match) !== false)) < // etc. break; >> foreach ($pattern_array as $pattern) < if (preg_match($pattern, $page)) < // etc. break; >> 

and avoiding as many preg_match() as possible is probably going to be your best gain. strpos() is a lot faster than preg_match() .

Источник

Оцените статью