在Perl中使用Regex进行搜索/替换时如何使用替换变量?

时间:2011-10-06 13:52:19

标签: regex perl

我想在xml文件中搜索所有-tags,将启用的属性更改为false,这可能是这样的

<repository store-diff="true" description="ACS" name="ACS" enabled="true">

还有其他标签也有启用属性所以我需要搜索以#开头的行,这很容易,问题是替换字符串。我试过这个:

perl -p -e 's#^<repository.*enabled="true"#$1enabled="false"#g' 

但没有运气,我试图改变的文件没有做任何改变。或者,这不是真的,它匹配,但我无法改变ONLY enabled =“true”将其设置为false,它会删除剩余的行,只留下启用=“false”......

根据http://refcards.com/docs/trusketti/perl-regexp/perl-regexp-refcard-a4.pdf

应该是可能的

2 个答案:

答案 0 :(得分:4)

#!/usr/bin/perl
use XML::Twig;
my $t = XML::Twig->new(
                       twig_handlers => {
                           # for repository tags, if it has the enabled
                           # attribute, set it to false.
                           repository => sub {
                               exists $_->{att}->{enabled} &&
                               $_->set_att(enabled => 'false');
                               $_->flush();
                           },
                       },
                      );
$t->parsefile($ARGV[0]);
$t->flush();

似乎适合我。您可能希望使用存储库标记的回调 - 我不确定您是否要始终将enabled属性设置为false,即使该属性不存在(删除该回调中的第一行)或仅属性就在那里。

好的,它不再是单行了。但如果你想要做得对,那不应该是要求。请注意,因为现在正在解析XML,我们需要一个格式良好的XML文档,我们不关心存储库标记是分布在多行上,还是一行上有多个,或者其他属性是什么等等。

它也不会落入你问题的“正则表达式”标签上。但那是因为我认为该标签正在将其变成XY问题。

答案 1 :(得分:-2)

我没有测试过,但我相信这会有效:

perl -p -e 's#^(<repository.*)enabled="true"#$1enabled="false"#g'

首先,您需要有一个组才能使用反向引用,因此您必须将表达式的一部分括起来,以便稍后引用。在这种情况下,我们需要从<repository一直到enabled...的所有内容,因此我们将该位括在括号中。