【问题标题】:Find and replace characters between XML tags查找和替换 XML 标记之间的字符
【发布时间】:2012-04-17 23:10:44
【问题描述】:

我有一个不受行约束的 XML 文件。它具有标签<tag1></tag1>,其中包含一些来自生成它的代码的废弃变量(我现在无法更正)。我希望能够更改这些标签中的字符以更正它们。这些字符有时很特殊。

我有这个 Perl 单行代码来显示标签之间的内容,但现在我希望能够在文件中替换它找到的内容。

perl -0777 -ne 'while (/(?<=perform_cnt).*?(?=\<\/perform_cnt)/s) {print $& . "\n";      s/perform_cnt.*?\<\/perform_cnt//s}' output_error.txt

这是一个 XML 示例。注意标签perform_cnt之间的垃圾字符。

<text1>120105728</text1><perform_cnt>ÈPm=</perform_cnt>
<text1>120106394</text1><perform_cnt>†AQ;4K\_Ô23{YYÔ@Nx</perform_cnt>

我需要将这些替换为 0。

【问题讨论】:

标签: xml perl


【解决方案1】:

我喜欢 XML::Twig 的这些东西。这需要一点时间来适应,但是一旦你了解了设计(以及一点关于 DOM 处理的知识),很多事情就会变得非常容易:

use XML::Twig;

my $xml = <<'HERE';
<root>
<text1>120105728</text1><perform_cnt>ÈPm=</perform_cnt>
<text1>120106394</text1><perform_cnt>†AQ;4K\_Ô23{YYÔ@Nx</perform_cnt>
</root>
HERE

my $twig = XML::Twig->new(   
    twig_handlers => { 
        perform_cnt   => sub { 
            say "Text is " => $_->text;  # get the current text

            $_->set_text( 'Buster' );    # set the new text
            },
      },
    pretty_print => 'indented',
    );

$twig->parse( $xml );
$twig->flush; 

通过缩进漂亮的打印,我得到:

<root>
  <text1>120105728</text1>
  <perform_cnt>Buster</perform_cnt>
  <text1>120106394</text1>
  <perform_cnt>Buster</perform_cnt>
</root>

【讨论】:

    【解决方案2】:

    使用正则表达式进行 xml 解析是一种不好的做法

    无论如何 - 代码是:

    #!/usr/bin/perl
    
    use strict;
    use warnings;
    
    my $tag = 'perform_cnt';
    
    open my $fh, '<file.txt' or die $!;
    foreach (<$fh>) {
      s/(<$tag>)(.*?)(<\/$tag>)/$1$3/g;
      print "$_";
    }
    close $fh;
    

    输出是:

    <text1>120105728</text1><perform_cnt></perform_cnt>
    <text1>120106394</text1><perform_cnt></perform_cnt>
    

    【讨论】:

    • 如果你想从输出中消除&lt;perform_cnt&gt;&lt;/perform_cnt&gt;,那么将代码中的/$1$3/替换为//
    • 另外,print "$_" 的输出不是最好的。使用print;
    • @loldop - 如果您正在寻找短代码,那么也许可以。否则我看不出有什么理由。短代码可以看起来像 s/(&lt;$tag&gt;)(.*?)(&lt;\/$tag&gt;)/$1$3/g &amp;&amp; print for &lt;$fh&gt;; 替换整个 foreach 循环。
    • 是一样的。如果需要,请使用print; print "\n"; print "$_\n";,但我通常使用say 函数say{ return (@_,"\n");}
    • @loldop - 我知道那是什么,但它不是标准用法,实际上say 来自 Perl 5.10+ 我相信,所以不是每个 Perl 都能得到它。
    猜你喜欢
    • 1970-01-01
    • 2015-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-25
    • 2014-12-03
    相关资源
    最近更新 更多