preg_match显示foreach循环中的第一个匹配项

Pie*_*rre 2 php regex preg-match

我有一系列模式:

$patterns= array(
    '#http://(www\.)?domain-1.com/.*#i',
    '#http://(www\.)?domain-2.com/.*#i',
    ...
);
Run Code Online (Sandbox Code Playgroud)

我有长字符串,包含多个文本和网址,我想匹配字符串中出现的第一个网址,我只试过这个:

foreach ($patterns as $pattern) {
    preg_match($pattern, $the_string, $match);
    echo '<pre>'; print_r($match); echo '</pre>';
}
Run Code Online (Sandbox Code Playgroud)

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

如何找到首先出现的这些模式的匹配项.

rod*_*ehm 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);
Run Code Online (Sandbox Code Playgroud)

请注意我改变了你的演示模式.我用.*(除了[^\s]*空间之外的所有东西)替换(任何东西)以防止模式匹配超出预期