【问题标题】:Regular Expression to extract all the links and the corresponding link text正则表达式提取所有链接和相应的链接文本
【发布时间】:2023-03-28 12:11:01
【问题描述】:

我是正则表达式的新手,我正在尝试解决以下两个问题:

  1. 编写一个正则表达式,从 HTML 页面中提取所有链接和相应的链接文本。例如,如果你想解析:

     text1 <a href="http://example.com">hello, world</a> text2
    

并得到结果

http://example.com <tab> hello, world
  1. 做同样的事情,但也处理 <...> 嵌套的情况:

      text1 <a href="http://example.com" onclick="javascript:alert('<b>text2</b>')">hello, world</a> text3
    

到目前为止,我仍然在第一个问题上,我已经尝试了几种方法。我认为我对第一个的最佳答案是正则表达式(?&lt;=a href=\")(.*)(?=&lt;/a&gt;),它给了我:http://example.com"&gt;hello, world

这对我来说似乎已经足够好了,但我不知道我应该如何处理第二部分。任何帮助或见解将不胜感激。

【问题讨论】:

  • 正则表达式不适合嵌套。你应该考虑一个真正的 html 解析器。
  • 那我该如何回答这个问题呢?只是说请不要使用正则表达式进行 html 解析?
  • 问题来自哪里?问题 2 似乎是您不会为此使用正则表达式的确切原因。
  • 我正在使用 regex101.com 测试这些,所以我使用的是 python 语法,但他们可能希望在 perl 中使用它。感谢@PatrickHaugh,(.*) 几乎给了我想要的结果。我对此非常陌生,以至于我真的不知道将结果分为第 1 组和第 2 组是否重要。

标签: javascript python regex perl


【解决方案1】:

如果您要使用像BeautifulSoup 这样的HTML 解析器 来解决它,只需找到a 元素,使用类似于字典的访问href 属性和get_text() 用于获取元素的文本:

In [1]: from bs4 import BeautifulSoup

In [2]: l = [
    """text1 <a href="http://example.com">hello, world</a> text2""", 
    """text1 <a href="http://example.com" onclick="javascript:alert('<b>text2</b>')">hello, world</a> text3"""
]

In [3]: for s in l:
            soup = BeautifulSoup(s, "html.parser")
            link = soup.a
            print(link["href"] + "\t" + link.get_text())
    ...:     
http://example.com  hello, world
http://example.com  hello, world

【讨论】:

    【解决方案2】:

    使用正则表达式,有时最好查看不应该捕获的内容,而不是获取想要的内容。这个 perl 正则表达式应该可靠地捕获简单链接及其相关文本:

    #!perl
    
    use strict;
    use warnings;
    
    my $sample = q{text1 <a href="http://example.com">hello, world</a> text2};
    
    my ($link, $link_text) = $sample =~ m{<a href="([^"]*)"[^>]*>(.*?)</a>};
    
    print "$link \t $link_text\n";
    
    1;
    

    这将打印:

    http://example.com <tab> hello, world
    

    分解它在做什么:

    第一个捕获,([^"]*),在 href 属性内寻找 0 个或多个不是双引号的字符。方括号用于列出一系列字符,前导克拉告诉正则表达式查找不在此范围内的任何字符。

    同样,我使用[^&gt;]*&gt; 来查找a 标签的右括号,而无需担心标签中可能包含哪些其他属性。

    最后,(.*?) 是一个 0 或多个非贪婪捕获(由问号表示),仅捕获该链接内的所有文本。如果没有非贪婪指示符,它会将所有文本匹配到文档中最后一个结束 &lt;/a&gt; 标记。

    希望这将帮助您解决作业的第 2 部分。 :)

    【讨论】:

      猜你喜欢
      • 2011-05-31
      • 2011-06-05
      • 2014-03-22
      • 1970-01-01
      • 1970-01-01
      • 2010-12-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多