如何从Perl中的字符串中提取特定标记之间的数据?

时间:2011-09-27 14:03:30

标签: xml perl substring

例如,来自以下字符串

<?xml version="1.0"?><root><point><message>hello world 1</message></point><point><data><message>hello world 2</message></data></point></root>

如果我想提取message,结果应为

hello world 1
hello world 2

有一种简单的方法吗?

我能想到的首先是找出位置,然后在循环中生成子串。还有更好的方法吗?

3 个答案:

答案 0 :(得分:3)

您的数据不是XML,因此我猜您必须使用正则表达式:

perl -n -E'say $1 while m{<message>(.*?)</message>}g' your_file_here.xml 

如果您的文件正确的XML,那么XML :: Twig可以很好地工作。您甚至可以使用随附的xml_grep工具来完成您想要的工作。

更新:您可以使用有效的XML

xml_grep --text_only message mes.xml 

xml_grep2 --text_only '//message' mes.xml # xml_grep2 is in App::xml_grep2

perl -MXML::Twig -E'XML::Twig->new( twig_handlers => 
                                      { message => sub { say $_->text; }, })
                             ->parsefile( "mes.xml")'

答案 1 :(得分:2)

使用XML解析器。在Subs模式下XML::Parser似乎已经足够了。

答案 2 :(得分:1)

使用XML解析器。我喜欢XML::LibXML

use strict;
use warnings;
use feature qw( say );

use XML::LibXML qw( );

my $xml = <<'__EOI__';
   <?xml version="1.0"?><root>
   <point><message>hello world 1</message></point>
   <point><data><message>hello world 2</message></data></point>
   </root>
__EOI__

my $parser = XML::LibXML->new();
my $doc    = $parser->parse_string($xml);
my $root   = $doc->documentElement();

say $_->textContent() for $root->findnodes('//message');