perl 提取 </SPAN> 和 <br> 之间的句子

Posted

技术标签:

【中文标题】perl 提取 </SPAN> 和 <br> 之间的句子【英文标题】:perl extract sentences between </SPAN> and <br> 【发布时间】:2014-01-27 17:47:51 【问题描述】:

我想提取 SPAN 和 br 之间的句子。我正在尝试使用 html::TreeBuilder。我是 perl 的新手。任何帮助将不胜感激。

<p>
<SPAN class="verse" id="1">1 </SPAN> ଆରମ୍ଭରେ ପରମେଶ୍ବର ଆକାଶ ଓ   ପୃଥିବୀକୁ ସୃଷ୍ଟି କଲେ।
<br><SPAN class="verse" id="2">2 </SPAN> ପୃଥିବୀ ସେତବେେଳେ ସଂପୂରନ୍ଭାବେ ଶୂନ୍ଯ ଓ କିଛି ନଥିଲା। ଜଳଭାଗ ଉପରେ ଅନ୍ଧକାର ଘାଡ଼ଇେେ ରଖିଥିଲା ଏବଂ ପରମେଶ୍ବରଙ୍କର ଆତ୍ମା ଜଳଭାଗ
<br><SPAN class="verse" id="3">3 </SPAN> ଉପରେ ବ୍ଯାପ୍ତ ଥିଲା।
<br><SPAN class="verse" id="4">4 </SPAN> ପରମେଶ୍ବର ଆଲୋକକୁ ଦେଖିଲେ ଏବଂ ସେ ଜାଣିଲେ, ତାହା ଉତ୍ତମ, ଏହାପ ରେ ପରମେଶ୍ବର ଆଲୋକକୁ ଅନ୍ଧକାରରୁ ଅଲଗା କଲେ।
</p>

我做了什么

 foreach $line (@lines)
    
        # Now create a new tree to parse the HTML from String $str
        my $tr = HTML::TreeBuilder->new_from_content($line);

        # And now find all <p> tags and create an array with the values.
        my @lists = 
              map  $_->content_list  
              $tr->find_by_tag_name('p');

        # And loop through the array returning our values.
        foreach my $val (@lists) 
        print $val, "\n";printf FILE1  "\n%s", $val ;
           


    

我无法跳过嵌套在 p 标签中的那些 html 标签。我只想提取 unicode 文本并跳过嵌套标签。

【问题讨论】:

到目前为止你做了什么,你的错误信息是什么? HTML::TreeBuilder 是一个很好的方法。请展示您的尝试。 @user1126070:我能够在开始和结束标记之间获取文本,例如 SPAN 和 /SPAN 之间的文本,但不能在任何随机标记之间获取。 【参考方案1】:

我会使用 XML::Twig,只是因为我熟悉它。在底层它使用 HTML::TreeBuilder 将 HTML 转换为 XHTML。

解决您的问题的一个简单方法是:

#!/usr/bin/perl

use strict;
use warnings;

use XML::Twig;

binmode( STDOUT, ':utf8'); # to avoid warnings when printing out wide (multi-byte) characters


my $file= shift @ARGV;

my $t= XML::Twig->new->parsefile_html( $file);

foreach my $p ($t->descendants( 'p'))
   $p->cut_children( 'span');              # HTML::TreeBuilder lowercases tags
    my @texts= $p->children_text( '#TEXT'); # just get the text
    print join "---\n", @texts;             # or do whatever with the text
  

【讨论】:

谢谢!如果我不知道子标签是什么(就像在这种情况下,我知道只有一个标签,那就是 SPAN 标签)以及有多少,那么我如何修改上面的代码以剪切所有子标签并只保留文本直接在父标签下? 是的,您可以使用$p-&gt;cut_children( '#ELT'); 剪切所有嵌套元素,但是您也剪切了 元素,您只会得到一个文本,或者您可以使用foreach my $child ($p-&gt;children( '#ELT')) $child-&gt;cut unless $child-&gt;tag eq 'br'; 来保留休息。【参考方案2】:

你当然可以使用正则表达式:-)

while ( $html =~ s!<span[^>]*>.*?</span>([^>]*)<br>!$1! )
  my $text = $1;

使用正则表达式修复原始代码仍然很容易。

    # And loop through the array returning our values.
    foreach my $val (@lists) 
        $val =~ s!<[^>]*>!!gis;
        print $val, "\n";printf FILE1  "\n%s", $val ;
      

正则表达式并不邪恶:http://www.codinghorror.com/blog/2008/06/regular-expressions-now-you-have-two-problems.html

正则表达式就像是一种特别辣的辣酱——to be 仅在适当的时候适度和克制地使用。

【讨论】:

@user1126070:谢谢。我能够得到我想要的。但我正在寻找更不稳定的解决方案,借助 html 解析,我可以将其与不同的网页一起使用,以获取嵌套在 html 标签之间的文本 正则表达式并不邪恶:codinghorror.com/blog/2008/06/… @user1126070 用于解析regular languages时并不邪恶,但HTML不是正则语言,因此不能被正则表达式解析。

以上是关于perl 提取 </SPAN> 和 <br> 之间的句子的主要内容,如果未能解决你的问题,请参考以下文章

perl 多fasta文件匹配,并提取匹配文件第一条序列

如何提取和忽略标记中的跨度? - Python

Perl 使用 XML Path Context 提取数据

正则表达式 提取内容

提取 HTML 标签之间的波斯文和英文字符

正则表达式将数字提取到组中