从字符串中提取url,之间没有空格

时间:2017-04-19 12:19:35

标签: php regex

假设我有一个这样的字符串:

$urlsString = "http://foo.com/barhttps://bar.com//foo.com/foo/bar"

我希望得到一个这样的数组:

array(
    [0] => "http://foo.com/bar",
    [1] => "https://bar.com",
    [0] => "//foo.com/foo/bar"
);

我正在寻找类似的东西:

preg_split("~((https?:)?//)~", $urlsString, PREG_SPLIT_NO_EMPTY|PREG_SPLIT_DELIM_CAPTURE);

PREG_SPLIT_DELIM_CAPTURE定义为:

如果设置了此标志,则将捕获并返回分隔符模式中带括号的表达式。

即上述preg_split返回:

array (size=3)
  0 => string '' (length=0)
  1 => string 'foo.com/bar' (length=11)
  2 => string 'bar.com//foo.com/foo/bar' (length=24)

知道我做错了什么或其他任何想法?

PS:我一直在使用this regex,直到我意识到它不包括这种情况。

修改

正如@sidyll指出的那样,我错过了$limit参数中的preg_split。无论如何,我的正则表达式有问题,所以我会使用@WiktorStribiżew建议。

1 个答案:

答案 0 :(得分:3)

您可以将preg_match_all与以下正则表达式一起使用:

'~(?:https?:)?//.*?(?=$|(?:https?:)?//)~'

请参阅regex demo

<强>详情:

  • (?:https?:)? - https:http:,可选(1或0次)
  • // - 加倍/
  • .*? - 除了换行之外的任何0 +字符尽可能少到第一个
  • (?=$|(?:https?:)?//) - 两者中的任何一个:
    • $ - 字符串结尾
    • (?:https?:)?// - https:http:,可选(1或0次),后跟双/

以下是PHP demo

$urlsString = "http://foo.com/barhttps://bar.com//foo.com/foo/bar";
preg_match_all('~(?:https?:)?//.*?(?=$|(?:https?:)?//)~', $urlsString, $urls);
print_r($urls);
// => Array ( [0] => http://foo.com/bar [1] => https://bar.com [2] => //foo.com/foo/bar )