Php preg_match显示foreach循环中的第一个匹配
我有一系列的模式:Php preg_match显示foreach循环中的第一个匹配,php,regex,preg-match,Php,Regex,Preg Match,我有一系列的模式: $patterns= array( '#http://(www\.)?domain-1.com/.*#i', '#http://(www\.)?domain-2.com/.*#i', ... ); 我有一个包含多个文本和url的长字符串,我想匹配字符串中出现的第一个url,我只尝试了以下方法: foreach ($patterns as $pattern) { preg_match($pattern, $the_string, $match)
$patterns= array(
'#http://(www\.)?domain-1.com/.*#i',
'#http://(www\.)?domain-2.com/.*#i',
...
);
我有一个包含多个文本和url的长字符串,我想匹配字符串中出现的第一个url,我只尝试了以下方法:
foreach ($patterns as $pattern) {
preg_match($pattern, $the_string, $match);
echo '<pre>'; print_r($match); echo '</pre>';
}
foreach($patterns作为$pattern){
preg_match($pattern,$the_string,$match);
回显“”;打印($match);回显“”;
<?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);
}
它返回空数组,其中某些模式与包含url的数组不匹配,但这取决于数组的顺序$patterns
我怎样才能找到这些最先出现的模式中的任何匹配项。我猜您正在寻找以下内容:
$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);
您基本上有三种选择:
PREG\u OFFSET\u CAPTURE
标志运行所有模式,以获得模式匹配的偏移量。找到最小偏移量,返回结果备选案文2:
除了一次评估所有字符串,并获取最早的字符串外,我想不出任何方法:
$easliestPos=strlen(_字符串)+1;
$earliestMatch=false;
foreach($patterns作为$pattern){
如果(preg_match($pattern,$the_string,$match)){
$myMatch=$match[0];
$myMatchPos=strpos($myMatch,$u字符串);
如果($myMatchPos<$easliestPos){
$easliestPos=$myMatchPos;
$earliestMatch=$myMatch;
}
}
}
如果($earliestMatch){
echo$earliestMatch;
}
您能给我们展示一个您试图匹配的URL示例和一个示例模式吗?问题可能在于你的正则表达式模式,而不是你的PHP。你键入它的速度比我快:)我不想在第一次匹配后停止,这将返回一个匹配,即使它位于字符串的末尾,但它的模式位于数组模式的开头。虽然这是一个可行的解决方案,但是ksort()
是对性能的不必要浪费…@rodneyrehm感谢您删除了它。我还是喜欢你的:)
<?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);
$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;
}