In this post I'll provide you with three different methods of doing what you ask for. I actually recommend using the last snippet, since it's easiest to comprehend as well as being quite neat in code.
How to get the matching elements of an array
There is a function dedicated for just this purpose, preg_grep. It will take a regular expression as first parameter, and an array as the second.
See the below example:
$haystack = array (
'say hello',
'hello stackoverflow',
'hello world',
'foo bar bas'
);
$matches = preg_grep ('/^hello (\w+)/i', $haystack);
print_r ($matches);
output
Array
(
[1] => hello stackoverflow
[2] => hello world
)
Documentation
- PHP: preg_grep - Manual
How to extract only the matching text from array elements?
array_reduce with preg_match can solve this issue in clean manner; see the snippet below.
$haystack = array (
'say hello',
'hello stackoverflow',
'hello world',
'foo bar bas'
);
function _matcher (
str) {
if (preg_match ('/^hello (\w+)/i',
matches))
matches[1];
return $m;
}
// N O T E :
// ------------------------------------------------------------------------------
// you could specify '_matcher' as an anonymous function directly to
// array_reduce though that kind of decreases readability and is therefore
// not recommended, but it is possible.
$matches = array_reduce ($haystack, '_matcher', array ());
print_r ($matches);
output
Array
(
[0] => stackoverflow
[1] => world
)
Documentation
- PHP: array_reduce - Manual
- PHP: preg_match - Manual
Using array_reduce seems tedious, is there another way?
Yes, and this one is actually cleaner though it doesn't involve using any pre-existing array_* or preg_* function.
Wrap it in a function if you are going to use this method more than once.
$matches = array ();
foreach ($haystack as $str)
if (preg_match ('/^hello (\w+)/i',
m))
$matches[] = $m[1];
Documentation
- PHP: preg_match - Manual
php - How to search in an array with preg_match? - Stack Overflow
preg_match an array as pattern
Does preg_match() work against arrays, or do I need to split the array into lines first?
How do you perform a preg_match where the pattern is an array, in php? - Stack Overflow
In this post I'll provide you with three different methods of doing what you ask for. I actually recommend using the last snippet, since it's easiest to comprehend as well as being quite neat in code.
How to get the matching elements of an array
There is a function dedicated for just this purpose, preg_grep. It will take a regular expression as first parameter, and an array as the second.
See the below example:
$haystack = array (
'say hello',
'hello stackoverflow',
'hello world',
'foo bar bas'
);
$matches = preg_grep ('/^hello (\w+)/i', $haystack);
print_r ($matches);
output
Array
(
[1] => hello stackoverflow
[2] => hello world
)
Documentation
- PHP: preg_grep - Manual
How to extract only the matching text from array elements?
array_reduce with preg_match can solve this issue in clean manner; see the snippet below.
$haystack = array (
'say hello',
'hello stackoverflow',
'hello world',
'foo bar bas'
);
function _matcher (
str) {
if (preg_match ('/^hello (\w+)/i',
matches))
matches[1];
return $m;
}
// N O T E :
// ------------------------------------------------------------------------------
// you could specify '_matcher' as an anonymous function directly to
// array_reduce though that kind of decreases readability and is therefore
// not recommended, but it is possible.
$matches = array_reduce ($haystack, '_matcher', array ());
print_r ($matches);
output
Array
(
[0] => stackoverflow
[1] => world
)
Documentation
- PHP: array_reduce - Manual
- PHP: preg_match - Manual
Using array_reduce seems tedious, is there another way?
Yes, and this one is actually cleaner though it doesn't involve using any pre-existing array_* or preg_* function.
Wrap it in a function if you are going to use this method more than once.
$matches = array ();
foreach ($haystack as $str)
if (preg_match ('/^hello (\w+)/i',
m))
$matches[] = $m[1];
Documentation
- PHP: preg_match - Manual
Use preg_grep
$array = preg_grep(
'/(my\n+string\n+)/i',
array( 'file' , 'my string => name', 'this')
);
This is an odd situation, but I'm having to learn to and start writing in PHP before I even have access to a machine that has any way of running/testing PHP code. I have a line where I basically want to do this:
if (preg_match($check_for, $check_in)){
yadda_yadda();
}
But in this case $check_in is an array. Will that work, or do I need to split the array into individual lines and then preg_match() against the individual lines? I suspect the latter, but want to confirm before I go through the trouble of writing that code.
TIA!
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.
So doing this:
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().
// assuming you have something like this
$patterns = array('a','b','\w');
// converts the array into a regex friendly or list
$patterns_flattened = implode('|', $patterns);
if ( preg_match('/'. $patterns_flattened .'/', $string, $matches) )
{
}
// PS: that's off the top of my head, I didn't check it in a code editor
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 { ... }
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