【问题标题】:Perl Regex for Not HTML非 HTML 的 Perl 正则表达式
【发布时间】:2023-03-30 04:07:01
【问题描述】:

我希望从 HTML 文档中替换任何不是 HTML 标记的内容。所以,基本上试图摆脱文档中的所有文本。

我有下面的正则表达式来从字符串中删除所有 HTML,但在相反的情况下需要帮助。

$string =~ s/<[^>]+>//g;

谢谢。

【问题讨论】:

  • NoooooooOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo stackoverflow.com/questions/1732348/…
  • 请不要这样做。这是去madness的路
  • 什么不是 HTML 文档中的 HTML 标签?如果它的格式正确,那么除了 cmets 之外的所有东西都会放在某种标签内。您是在正文内而不是在另一个标签内寻找文本吗?
  • @Ethan Brown:是的,希望消除不在 HTML 标记中的文本。
  • 你没有真正回答我的问题。例如,如果这是您的文档:&lt;html&gt;&lt;body&gt;Here's some &lt;b&gt;bold&lt;/b&gt; text!&lt;/body&gt;&lt;/html&gt;,您是否在寻找字符串“Here's some”和“text!”?因为这些字符串都不在 HTML 标记之外(它们都在 &lt;body&gt; 标记内)。

标签: html regex perl tags


【解决方案1】:

Ethan Brown 对 HTML::DOM 进行名称检查,就好像它是唯一的 CPAN 解决方案。

HTML::Parser 更加普遍,但谷歌搜索更多内容并不难。

http://metacpan.org/pod/HTML::Parser

使用 HTML::Parser 的解决方案是(测试一次):

use HTML::Parser ();

my $p = HTML::Parser->new(api_version => 3);
$p->handler( text => sub { }, "");
$p->handler( default => sub { print shift }, "text");
$p->parse_file('content.html') || die $!;

【讨论】:

    【解决方案2】:

    LibXML 可以轻松选择不是标签/cmets/processing-instruction 的内容并将其删除

    #!/usr/bin/perl --
    use strict;
    use warnings;
    use XML::LibXML 1.70; ## for load_html/load_xml/location
    use XML::LibXML::PrettyPrint;
    
    Main( @ARGV );
    exit( 0 );
    sub Main {
        binmode STDOUT;
        my $loc = shift or die "
    Usage:
        $0  ko00010.html
        $0  http://example.com/ko00010.html\n\n";
    
        my $dom = XML::LibXML->new(
            qw/
              recover 2
              no_blanks 1
              /
        )->load_html( location => $loc, );
    
    ## http://www.w3.org/TR/xpath/#node-tests
    ## http://www.w3.org/TR/xpath/#NT-NodeType
    ## http://www.w3.org/TR/xpath/#section-Text-Nodes
        for my $text ( $dom->findnodes(q{ //text() }) ){
            node_detach( $text );
        }
    
    
        local $XML::LibXML::skipXMLDeclaration = 1; ## <?xml ?>
        local $XML::LibXML::setTagCompression = 0;  ## <p />
    
    #~     print "$dom";
    
        my $pp  = XML::LibXML::PrettyPrint->new_for_html;
        $pp->{indent_string}=' ';
        print $pp->pretty_print( $dom );
    }
    sub node_detach {
        my( $self ) = @_;
        $self->parentNode->removeChild( $self );
    }
    

    【讨论】:

    • 值得注意的是,任何兼容的基于 DOM 的解决方案都会将 HTML 片段包装在一个最小的&lt;html&gt;&lt;body&gt;... 片段中。此解析器还坚持 HTML4 语义(与 HTML5 相比),并将在我们的输入中没有结束标记的地方引入结束标记。
    【解决方案3】:

    如果这是正则表达式 s///从文档中删除所有 html 的替换

    $string =~ s/<[^>]+>//g;
    

    然后您可以在 m//atch 运算符中使用相同的正则表达式来保留文档中的所有 html

    $string = join '', $string =~ m/<[^>]+>/g;
    

    如果上述正则表达式满足您的要求,那么您就完成了 :) 但也许您想考虑这个 ol' 正则表达式模式,稍微长一点:D http://perlmonks.org/?node_id=161281 请注意 Ethan Browne 提到的注意事项 :)

    【讨论】:

    • 这个想法(提取所有标签)比删除标签之间的任何东西要好。但是,&lt;!-- &gt; --&gt;&lt;!-- &gt;&lt;script&gt; 3 &lt; 4 &lt;/script&gt;&lt;script&gt;&lt; 4 &lt;/script&gt; 的正则表达式失败。仍然 +1 用于链接到更好的正则表达式。
    • :) 你已经说过 amon,它的 OPs 正则表达式没有改变 :)
    【解决方案4】:

    你在找这个吗?

    $string =~ s/>[^<]*</></mg;
    

    还是这个?

    $string =~ s/(?<=>)[^<]*(?=<)//mg;
    

    【讨论】:

    • 您的解决方案在 &lt;!-- &gt; --&gt;&lt;p&gt;--&gt;&lt;p&gt; 等 cmets 和 script&lt;script&gt; 2 &lt; 4 &lt;/script&gt;&lt;script&gt;&lt; 4 &lt;/script&gt; 等标签上失败。此外,不会删除文档末尾没有明确头部或正文的文本:&lt;h1&gt;Headline&lt;/h1&gt;&lt;p&gt;Text until EOF&lt;h1&gt;&lt;/h1&gt;&lt;p&gt;Text until EOF
    猜你喜欢
    • 2014-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多