2

我有一系列模式:

$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>';
}

它返回空数组,其中某些模式和包含 url 但取决于数组顺序的数组不匹配$patterns

我怎样才能找到首先发生的这些模式的任何匹配项。

4

3 回答 3

5

你基本上有三个选择:

  1. 匹配一个通用的 URL 模式,然后根据你所拥有的模式运行该 URL。如果没有匹配,则继续使用通用模式的第二个结果。
  2. 使用标志运行所有模式PREG_OFFSET_CAPTURE以获得模式匹配的偏移量。找到最低的偏移量,返回你的结果
  3. 将您的各种模式组合成一个模式。请注意,模式的长度有限制(编译形式为 64K

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

请注意,我更改了您的演示模式。我将.*(anything)替换为[^\s]*(everything but space) 以防止模式匹配超出预期

于 2012-06-26T13:08:05.120 回答
2

我猜你正在寻找这个:

foreach ($patterns as $pattern) {
    if (preg_match($pattern, $the_string, $match)) {
        echo '<pre>'; print_r($match); echo '</pre>';
        break;
    }
}

更新:

然后我认为你应该使用偏移链接这个:

$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);
于 2012-06-26T12:50:35.180 回答
1

除了一次评估所有字符串并抓住最早的字符串之外,我想不出任何办法:

$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;
 }
于 2012-06-26T13:13:47.103 回答