我有一个Perl脚本,我想修改它以删除两个XML标记之间的空格。
示例XML:
<TAG>
<TAG1><TAG2>abc 123 def 456 ... </TAG2></TAG1><TAG1><TAG2>xyz 987 ... </TAG>
我想删除所有TAG2
标记之间出现的所有空格。我尝试了以下方法:
$vModStrg =~ s/(<TAG2>(.*?)<\/TAG2>)/<TAG2>zzzzzz<\/TAG2>/g;
但这会将整个匹配替换为zzzzz
。如何告诉Perl只删除TAG2
所有匹配项的匹配空格?
答案 0 :(得分:2)
正则表达式对于这项工作来说是一个糟糕的工具,因为解析XML需要递归。您可以使用较新版本的正则表达式来实现这一点,但最多会导致非常复杂且难以阅读的正则表达式,以及具有边缘情况的正则表达式,这些正则表达式将会中断。
请参阅:Why it's not possible to use regex to parse HTML/XML: a formal explanation in layman's terms
所以使用解析器 - 删除<TAG2>
元素之间的空格&#39;:
#!/usr/bin/env perl
use strict;
use warnings;
use XML::Twig;
#parse the data from our "DATA" filehandle.
#you might want "parsefile('somefilename.xml')" instead.
my $twig = XML::Twig -> parse ( \*DATA );
#iterate 'text' below "TAG2" anywhere in the document.
foreach my $tag ( $twig -> get_xpath ('//TAG2/#TEXT') ) {
#modify this tag.
$tag -> set_text($tag -> text =~ s/\s+//gr );
}
#set output options
$twig -> set_pretty_print('indented_a');
#print to STDOUT. You might want:
#print {$output_fh} $twig -> sprint;
$twig -> print;
__DATA__
<root>
<TAG2>words with spaces</TAG2>
<TAG2>
<child>wordswordswords more words
</child>
</TAG2>
<TAG1>some more words with spaces</TAG1>
<TAG2>something here
<another_child att="fish" />
</TAG2>
</root>
输出:
<root>
<TAG2>wordswithspaces</TAG2>
<TAG2>
<child>wordswordswords more words
</child>
</TAG2>
<TAG1>some more words with spaces</TAG1>
<TAG2>somethinghere<another_child att="fish" /></TAG2>
</root>
正如您所看到的 - 正确修改<TAG2>
元素之间的文本,并保持其他内容不变。对于奖励积分,它至少同样清楚它作为同等正则表达式所做的事情!