获取多行的所有URL

时间:2015-02-28 15:38:19

标签: php regex

我试图从网站上获取所有这些网址,但我似乎只能获得第一个网址。如何匹配所有网址?

到目前为止,我已经尝试了

auto">(.*?)<\/pre>

auto">(.*?)\s<\/pre>

我已尝试添加多个修饰符,例如mi,但它似乎没有帮助。

这就是我正在搜索的内容:

auto">http://url-one.com
http://url-two.com
http://url-three.com
http://url-four.com
http://url-five.com</pre>

有人能帮我理解我错过的东西吗?

1 个答案:

答案 0 :(得分:2)

快速回答

正如Jonny5在评论中暗示的那样,默认情况下.与换行字符不匹配:因此(.*?)s正则表达式修饰符之后的第一行不匹配,他的建议是然后快速回答:

/auto">(.*?)<\/pre>/s

您可以查看他的Regex101 demo或相关的PHP代码......

$re = "/auto\">(.*?)<\\/pre>/s"; 
$str = "auto\">http://url-one.com\nhttp://url-two.com\nhttp://url-three.com\nhttp://url-four.com\nhttp://url-five.com</pre>"; 

preg_match($re, $str, $matches);

......供参考。

深入挖掘

然而,这里还有一点点。

i和m修饰符

首先,无论您使用i还是m修饰符,示例文本的任何行都不会与auto">匹配模式结尾处的 <\/pre>。您必须使用量词对每个元素进行分组和跟踪,以使其成为可选项(例如(?:auto">)?(?:<\/pre>)?)以匹配示例文本的每一行。

m需要全球匹配

第二个m修饰符需要全局匹配 - 并对模式进行进一步调整,以避免最后一个网址匹配以</pre>结尾:

/(?:auto">)?(.+)(?=(?:\n|<\/pre>))/m

您还可以查看second Regex101 demo此扭曲或在PHP中试用:

$re = "/(?:auto\">)?(.+)(?=(?:\\n|<\\/pre>))/m"; 
$str = "auto\">http://url-one.com\nhttp://url-two.com\nhttp://url-three.com\nhttp://url-four.com\nhttp://url-five.com</pre>"; 

preg_match_all($re, $str, $matches); // NOTE: preg_match_all to match globally
                                                        ^^^^

选择哪种方法

简单地添加s修饰符或调整模式,添加m修饰符以及全局匹配之间的选择主要取决于您是否希望与所有网址匹配(由换行符分隔) )许多匹配,每个匹配都有一个URL。

后者产生以下匹配......

MATCH 1
1.  [6-24]   `http://url-one.com`
MATCH 2
1.  [25-43]  `http://url-two.com`
MATCH 3
1.  [44-64]  `http://url-three.com`
MATCH 4
1.  [65-84]  `http://url-four.com`
MATCH 5
1.  [85-104] `http://url-five.com`

...与原始模式和s修饰符产生的单一匹配:

MATCH 1
1.  [6-104] `http://url-one.com
             http://url-two.com
             http://url-three.com
             http://url-four.com
             http://url-five.com`