PHP regexp(preg_match_all)-查找所有独立链接

时间:2019-05-09 11:43:33

标签: php regex preg-match-all

我的文字形式为:

Txx8xxTT<br><br><br>https://wwww.xxx.com<br><br />
<br />cxyc[link=http://www.example.com]link[/odkaz]
xxx<a href="http://www.example2.com">link2</a>

我想使用preg_match_all解析它,其中结果数组中所有独立链接都位于单独的索引处。在示例情况下,我想要这样的东西:

[0] => Txx8xxTT<br><br><br>
[1] => https://wwww.xxx.com
[2] => <br><br />
    <br />cxyc[link=http://www.example.com]link[/odkaz]
    xxx<a href="http://www.example2.com">link2</a>

(数组的格式可以不同,我不在乎索引,但是我想在其自己的索引处使用单独的链接)

我尝试将preg_match_all(.[^ \<\[]*)一起使用。几乎可以使用,但是我在索引[3]处得到的结果是<br>https://wwww.xxx.com,在这里我不需要<br>前缀。

[0] => Txx8xxTT
[1] => <br>
[2] => <br>
[3] => <br>https://wwww.xxx.com
[4] => <br>
[5] => <br
[6] =>  /> 
[7] => <br
[8] =>  />cxyc
[9] => [link="http://www.example.com"]link
[10] => [/odkaz]xxx
[11] => <a
[12] =>  href="http://www.example2.com">link2
[13] => </a>

2 个答案:

答案 0 :(得分:3)

可能最好是:

  1. 通过HTML / DOM解析器解析输入
  2. 使用DOM / XPath查找文本节点
  3. 使用正则表达式提取网址

此处有1和2的示例: https://stackoverflow.com/a/6399988/406712

然后为您的正则表达式考虑“负向后看”,以排除以“ [link =:

”开头的链接

使用

preg_match_all('/(?<!\[link=)\bhttps?:\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[A-Z0-9+&@#\/%=~_|]/i', $subject, $result, PREG_PATTERN_ORDER);
for ($i = 0; $i < count($result[0]); $i++) {
    # Matched text = $result[0][$i];
}

正则表达式

(?<!\[link=)\bhttps?://[-A-Z0-9+&@#/%?=~_|!:,.;]*[A-Z0-9+&@#/%=~_|]

可视化

Regex Visualization

PS。如果要修改HTML输入,请使用DOM方法。

答案 1 :(得分:2)

请参阅上面的我的评论,解释使用regex解析html的恐怖现象。这确实不是最好的方法。 DOMDocument可能是一个更好的主意。

如果您只想要一组链接,可以尝试一下。我什么也不保证。

#https?:\/\/[a-z1-9\.]+#

这将返回:

Match 1
Full match  20-40   https://wwww.xxx.com
Match 2
Full match  67-89   http://www.example.com
Match 3
Full match  115-138 http://www.example2.com

https://regex101.com/r/Sh5CTa/1

更新 因为您不想要href =或link =,可以尝试一下吗?

#>(?<link>https?:\/\/[a-z1-9\.]+)<#

它使用一个命名的捕获组,因此它是$ matches ['link']

https://regex101.com/r/Sh5CTa/2