【问题标题】:perl to strip span tags around wordsperl 去除单词周围的 span 标签
【发布时间】:2017-08-19 05:13:46
【问题描述】:

我正在尝试使用以 0. 或 1 开头的字母间距去除 span 标签。

'<span style="letter-spacing:0.50 px">Boulevard,</span> '
to equal
'Boulevard, '

谢谢

这是一个完整行的示例。

<span style="letter-spacing:1.33 px">PRODUCTS</span> <span style="letter-spacing:1.37 px">MODEL</span> <span style="letter-spacing:0.77 px">HPI-27C</span> <span style="letter-spacing:1.39 px">MODDED)</span> ; <span style="letter-spacing:1.12 px">(HIGHWAY</span> <span style="letter-spacing:1.33 px">PRODUCTS</span> <span style="letter-spacing:1.37 px">MODEL</span>

需要像这样结束

产品型号 HPI-27C MODDED) ; (公路产品型号

【问题讨论】:

  • 使用 XML/HTML 解析器(xmllint、xmlstarlet ...)。
  • 你能给我指点一个教程,这样我就可以弄清楚如何解决这个问题。谢谢
  • 要求推荐或查找书籍、工具、软件库、教程或其他非现场资源的问题对于 Stack Overflow 来说是无关紧要的,因为它们往往会吸引固执己见的答案和垃圾邮件。对不起。

标签: perl sed replace


【解决方案1】:

Perl 单行代码:

1.) 使用Mojo::DOM58 模块

perl -0777 -MMojo::DOM58 -E '$d=Mojo::DOM58->new(<>);$d->find("span")->grep(qr/letter-spacing:[01]/)->map(sub{$_->strip});print "$d"' <file.html

2.) 或者如果您安装了Mojolicious,您可以将ojo 模块用作:

perl -Mojo -E '$d=x(f("file.html")->slurp);$d->find("span")->grep(qr/letter-spacing:[01]/)->map(sub{$_->strip});print "$d"'

两个示例打印:

PRODUCTS MODEL HPI-27C MODDED) ; (HIGHWAY PRODUCTS MODEL

【讨论】:

    【解决方案2】:

    这是一个使用 Perl 和 HTML::Parser 的示例:

    use strict;
    use warnings;
    use HTML::Parser ();
    my $delete_tag = 0;
    
    my $p = HTML::Parser->new(
        api_version => 3,
        default_h => [sub { print shift }, 'text'],
        start_h => [\&start_handler, 'tagname,text,attr'],
        end_h => [\&end_handler, 'tagname,text'],    
    );
    
    my $str = do { local $/; <DATA> };
    $p->parse($str) || die $!;
    print "\n";
    
    sub end_handler {
        my ( $tag, $text ) = @_;
        if ( $tag eq "span" ) {
            if ($delete_tag) {
                $delete_tag = 0;
                return;
            }
        }
        print $text;
    }
    
    sub start_handler {
        my ( $tag, $text, $attr ) = @_;
        if ( $tag eq "span" ) {
            if ($attr->{style} =~ /letter-spacing:[01]\./) {
                $delete_tag = 1;
                return;
            }
        }
        print $text;
    }
    
    __DATA__
    <span style="letter-spacing:1.33 px">PRODUCTS</span> <span style="letter-spacing:1.37 px">MODEL</span> <span style="letter-spacing:0.77 px">HPI-27C</span> <span style="letter-spacing:1.39 px">MODDED)</span> ; <span style="letter-spacing:1.12 px">(HIGHWAY</span> <span style="letter-spacing:1.33 px">PRODUCTS</span> <span style="letter-spacing:1.37 px">MODEL</span>
    

    输出

    PRODUCTS MODEL HPI-27C MODDED) ; (HIGHWAY PRODUCTS MODEL
    

    【讨论】:

      【解决方案3】:

      根据您发布的 1 个示例行,不完全可靠,但可以满足您的要求:

      $ sed -E 's#<span[^>]+letter-spacing:[01][^>]+>(.*)</span>#\1#' file
      'Boulevard, '
      

      以上内容适用于任何支持 ERE 的 -E 的 sed,例如GNU sed 和 OSX sed。

      鉴于您更新的示例输入/输出,这将满足您对多字符 RS 和 RT 的 GNU awk 的要求:

      $ awk -v RS='</span>' '{ORS=( sub(/<span[^>]+letter-spacing:[01][^>]+>/,"") ? "" : RT)}1' file
      PRODUCTS MODEL HPI-27C MODDED) ; (HIGHWAY PRODUCTS MODEL
      

      【讨论】:

      • 这有帮助,但是当每行有多个实例时,我会得到这个“Total TASK-HR 是 tine 需要做 所有服务(根据条件或"
      • 我们所要做的就是您向我们展示的内容。您没有向我们展示在 1 行上有多个实例的示例,因此 YMMV 提供了您得到的答案。如果您问题中的示例不能真正代表您的真实数据,那么显然,请编辑您的问题。
      • 完美。谢谢
      猜你喜欢
      • 2012-11-17
      • 1970-01-01
      • 1970-01-01
      • 2014-11-14
      • 2011-03-11
      • 1970-01-01
      • 2013-09-15
      • 2011-05-15
      • 2015-07-02
      相关资源
      最近更新 更多