【问题标题】:PHP regexp (preg_match_all) - find all standalone linksPHP regexp (preg_match_all) - 查找所有独立链接
【发布时间】:2019-09-27 05:53:55
【问题描述】:

我的文本格式为:

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(.[^ \&lt;\[]*) 一起使用。它几乎可以工作,但我在索引 [3] 处得到的结果为 &lt;br&gt;https://wwww.xxx.com,我不想要 &lt;br&gt; 前缀。

[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>

【问题讨论】:

标签: php regex preg-match-all


【解决方案1】:

可能最好:

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

可以在此处找到 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+&@#/%=~_|]

可视化

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

【讨论】:

    【解决方案2】:

    请参阅我上面的评论,解释使用正则表达式解析 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

    【讨论】:

    • 我不想要所有链接,只需要独立的链接,因为我需要用 href 和其他“装饰”包装它们。我的正则表达式正常工作,唯一的问题是我想从 [3] 中删除 &lt;br&gt;。我可以用 PHP 做到这一点,但似乎我在我的正则表达式中遗漏了一些东西,这比使用 PHP 进行匹配更合法。
    • 独立是什么意思?
    • @delboy1978uk 独立链接 = 不在 href 或我自己的 [link=]
    猜你喜欢
    • 2013-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-11
    • 1970-01-01
    • 1970-01-01
    • 2011-08-29
    • 1970-01-01
    相关资源
    最近更新 更多