2017-04-19 29 views
2

之间的空间让我们说我有一个这样的字符串:提取URL没有

$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指出,我的思念在preg_split参数$limit。无论如何,我的正则表达式有问题,所以我会使用@WiktorStribiżew建议。

+1

'preg_split'有四个参数,第三个是限制。你通过限制标志。标志是第四个参数。但是,这不会产生你所期望的。DELIM_CAPTURE将分隔符分隔为自己的元素,并且您的正则表达式会导致分隔符(与http://和//(与两个分隔符相同)的匹配模糊) – sidyll

+0

哦!你是对的。谢谢 – Manolo

回答

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) 
+0

谢谢!只有一个问题:第一个'?:'是什么意思? – Manolo

+1

请参阅[什么是非捕获组?问号后跟冒号(?:)是什么意思?](http://stackoverflow.com/questions/3512471/what-is-a-non-capturing-group-what-does-a-question-mark -followed逐一个冒号)。 –

+0

我想我明白了。再次感谢。 – Manolo