想要检测多个网址时preg_match无法正常工作

时间:2015-12-24 22:02:01

标签: php url preg-replace preg-match

我想自动检测字符串中的任何链接,并用[index of link]替换它们。例如,如果我有一个类似test https://www.google.com/ mmh http://stackoverflow.com/的字符串,则结果为test [0] mmh [1]

现在我尝试了这个

$reg_exUrl = '/\b(?:(?:https?|ftp):\/\/|www\.)[-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/%=~_|]/i';
if(preg_match($reg_exUrl, $_POST['commento'], $url)) {
    for ($i = 0; $i < count($url); $i++) { 
        $_POST['commento'] = preg_replace($reg_exUrl, "[" . $i . "]", $_POST['commento']);
    }
}

但是我一直在test [0] mmh [0],如果我尝试var_dump(count($url))我总是得到1。我该如何解决这个问题?

1 个答案:

答案 0 :(得分:3)

因此,这里更好的解决方案是将传入的字符串拆分为每个url段之间的字符串数组,然后在连续的非url组件之间插入[$i]

# better solution, perform a split.
function process_line2($input) {
    $regex_url = '/\b(?:(?:https?|ftp):\/\/|www\.)[-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/%=~_|]/i';
    # split the incoming string into an array of non-url segments
    # preg_split does not trim leading or trailing empty segments
    $non_url_segments = preg_split($regex_url, $input, -1);

    # inside the array, combine each successive non-url segment
    # with the next index
    $out = [];
    $count = count($non_url_segments);
    for ($i = 0; $i < $count; $i++) {
        # add the segment
        array_push($out, $non_url_segments[$i]);
        # add its index surrounded by brackets on all segments but the last one
        if ($i < $count -1) {
            array_push($out, '[' . $i . ']');
        }
    }
    # join strings with no whitespace
    return implode('', $out);
}

preg_match仅返回第一个结果,因此它不会为您提供与正则表达式匹配的网址数。您需要提取preg_match_all返回的数组的第一个元素。

第二个错误是您没有使用limit的{​​{1}}参数,因此您的所有网址都会同时被替换。

来自preg_replace的文档:http://php.net/manual/en/function.preg-replace.php

参数是

  

混合preg_replace(混合$ pattern,混合$替换,混合$ subject [,int $ limit = -1 [,int&amp; $ count]])

特别是limit参数默认为preg_replace(无限制)

  

limit:每个主题字符串中每个模式的最大可能替换次数。默认为-1(无限制)。

您需要设置明确的限制为1。

在用-1替换preg_match时,您需要从中提取[0]组件,因为preg_match_all返回一个数组数组。例如:

preg_match_all

这是一个包含修复程序的示例。

array(1) {
  [0]=>
  array(2) {
    [0]=>
    string(23) "https://www.google.com/"
    [1]=>
    string(25) "http://stackoverflow.com/"
  }
}