Reputation: 13046
I have an array of patterns:
$patterns= array(
'#http://(www\.)?domain-1.com/.*#i',
'#http://(www\.)?domain-2.com/.*#i',
...
);
and I have long string that contains multiple text and urls I want to match the first url occurred in the string, I only tried this :
foreach ($patterns as $pattern) {
preg_match($pattern, $the_string, $match);
echo '<pre>'; print_r($match); echo '</pre>';
}
It returns empty arrays where there are no match for some patterns and arrays that contains a url but depending on the order of the array $patterns
,
how can I find any match of these patterns that occurred first.
Upvotes: 2
Views: 2482
Reputation: 3019
I guess you're looking for this:
foreach ($patterns as $pattern) {
if (preg_match($pattern, $the_string, $match)) {
echo '<pre>'; print_r($match); echo '</pre>';
break;
}
}
UPDATE:
Then I think you should work with offsets linke this:
$matches = array();
foreach ($patterns as $pattern) {
if (preg_match($pattern, $the_string, $match, PREG_OFFSET_CAPTURE)) {
$matches[$match[0][1]] = $match[0][0];
}
}
echo reset($matches);
Upvotes: 2
Reputation: 13557
You basically have three options:
PREG_OFFSET_CAPTURE
flag to get the offset the pattern matched at. find the lowest offset, return your resultOption 2:
<?php
$text = "hello world http://www.domain-2.com/foo comes before http://www.domain-1.com/bar";
$patterns= array(
'#http://(www\.)?domain-1.com/[^\s]*#i',
'#http://(www\.)?domain-2.com/[^\s]*#i',
);
$match = null;
$offset = null;
foreach ($patterns as $pattern) {
if (preg_match($pattern, $text, $matches, PREG_OFFSET_CAPTURE)) {
if ($matches[0][1] < $offset || $offset === null) {
$offset = $matches[0][1];
$match = $matches[0][0];
}
}
}
var_dump($match);
beware that I changed your demo patterns. I replaced .*
(anything) by [^\s]*
(everything but space) to prevent the pattern from matching more than it's supposed to
Upvotes: 5
Reputation: 17710
I can't think of any way except evaluting all the strings one at a time, and grabbing the earliest:
$easliestPos = strlen($the_string) + 1;
$earliestMatch = false;
foreach ($patterns as $pattern) {
if (preg_match($pattern, $the_string, $match)) {
$myMatch = $match[0];
$myMatchPos = strpos($myMatch, $the_string);
if ($myMatchPos < $easliestPos ) {
$easliestPos = $myMatchPos;
$earliestMatch = $myMatch ;
}
}
}
if ($earliestMatch ) {
echo $earliestMatch;
}
Upvotes: 1