【问题标题】:sed/grep - get text between two strings (html)sed/grep - 获取两个字符串之间的文本 (html)
【发布时间】:2014-10-03 15:57:46
【问题描述】:

我正在尝试从以下内容中提取“页面名称”:

<a class="timetable work" href="http://www.test.com/pagename?tag=meta376">Test</a>

我尝试使用“sed”让它工作,但它只显示无效的命令代码。

你们建议使用哪一行代码来获取页面名称?顺便说一句:这不是一行,但同一行上有更多内容 - 但这不应该有所作为,因为限制器之间应该有什么关系,对吧?

提前感谢您帮助我!

【问题讨论】:

  • 您是否要从该行中提取单词“pagename”?请显示您想要的输出示例。
  • 您要提取的究竟是什么?
  • 好吧,我尝试获取“pagename”,是的。但是文档很大,有很多链接。所以限制器应该在&lt;a class="timetable work" href="http://www.test.com/?tag=meta376"&gt;Test&lt;/a&gt;之间
  • 正确的方法是解析 HTML。在 Perl、Python、Ruby 或其他脚本语言中使用 HTML 解析器。通过其标签/类名获取元素。获取 href 属性。解析 URL 并提取路径。

标签: regex macos bash unix sed


【解决方案1】:

正如您所评论的,如果您想提取"&lt;a class="timetable work" href="test.com/"; and "?tag=meta376"&gt;Test&lt;/a&gt;",您可以使用以下正则表达式:

<a class="timetable.*?<\/a>

Working demo

如果您想获取内容,只需在正则表达式周围加上捕获组:

(<a class="timetable.*?<\/a>)

比赛是:

MATCH 1
1.  [9-80]  `<a class="timetable work" href="test.com/"; and "?tag=meta376">Test</a>`

【讨论】:

    【解决方案2】:

    我想这就是你想要的:

    sed 's_^.*<a [^<>]* href="https*://[^/]*/\([^"?]*\).*$_\1_'
    

    【讨论】:

      【解决方案3】:

      使用您告诉我们使用的分隔符准确地为您提供您所要求的内容:

      $ sed -n 's|.*<a class="timetable work" href="http://www\.test\.com/\(.*\)?tag=meta376">Test</a>|\1|p' file
      pagename
      

      【讨论】:

        【解决方案4】:

        我知道使用正则表达式处理这个问题可能很诱人,但这里有一个替代方法。

        您正在尝试解析一些 HTML,因此请使用 HTML 解析器。这是 Perl 中的一个示例:

        use strict;
        use warnings;
        use feature qw(say);
        
        use HTML::TokeParser::Simple;
        use URI::URL;
        
        my $filename = 'file.html'; 
        my $parser = HTML::TokeParser::Simple->new($filename);
        
        while (my $anchor = $parser->get_tag('a')) {
            next unless defined(my $class = $anchor->get_attr('class'));
            next unless $class =~ /\btimetable\b/ and $class =~ /\bwork\b/;    
            my $url = url $anchor->get_attr('href');    
            say substr($url->path, 1);
        }
        

        使用 HTML::TokeParser::Simple 解析 HTML。遍历&lt;a&gt; 标签,跳过任何没有定义正确类的标签。对于那些这样做的人,使用URI::URL 解析url并提取“路径”组件(在您的情况下,将是“/ pagename”)。由于您不想要前导斜杠,因此我使用 substr 删除了第一个字符。

        输出:

        pagename
        

        我知道它比单个正则表达式要长得多,但它也更加健壮很多,即使将来您的 HTML 格式略有变化,它也会继续工作。 HTML 解析器的存在是有原因的 :)

        【讨论】:

          【解决方案5】:

          我会为此使用awk

          awk -F"[/?]" '/timetable work/ {print $4}'file
          pagename
          

          它搜索包含timetable work 的行,然后使用\? 作为分隔符打印第四个字段。

          【讨论】:

            猜你喜欢
            • 2013-05-14
            • 1970-01-01
            • 2021-07-23
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-01-25
            • 1970-01-01
            相关资源
            最近更新 更多