简体   繁体   English

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

[英]How do I use replacement variables when doing search/replace with Regex in Perl?

I want to search a xml-file for all -tags changing the attribute enabled to false, which can be like this 我想在xml文件中搜索所有-tags,将启用的属性更改为false,这可能是这样的

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

There are other tags as well having the enabled attribute so I need to search for lines starting with , which is quite easy, problem is the replacement string. 还有其他标签也有启用属性,所以我需要搜索开头的行,这很容易,问题是替换字符串。 I've tried this: 我试过这个:

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

But no luck, no changes done to the file I try to change. 但没有运气,我试图改变的文件没有做任何改变。 Or, that's not true, it matches, but I'm not able to change ONLY enabled="true" setting it to false, it removes the rest of the line leaving it with just enabled="false"... 或者,这不是真的,它匹配,但我无法改变ONLY enabled =“true”将其设置为false,它会删除剩余的行,只留下启用=“false”...

Should be possible according to http://refcards.com/docs/trusketti/perl-regexp/perl-regexp-refcard-a4.pdf 应该可以根据http://refcards.com/docs/trusketti/perl-regexp/perl-regexp-refcard-a4.pdf

#!/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();

Seems to work for me. 似乎为我工作。 You may want to play with the callback for the repository tag - I'm not sure if you want to always set the enabled attribute to false, even if the attribute isn't there (delete the first line in that callback) or only if the attribute is there. 您可能希望使用存储库标记的回调 - 我不确定您是否要始终将enabled属性设置为false,即使该属性不存在(删除该回调中的第一行)或仅属性就在那里。

Okay, it's not a one-liner anymore. 好吧,它不再是单线程了。 But that shouldn't be the requirement if you want it done right. 但如果你想要做得对,那不应该是要求。 Note that because this is parsing XML now, we require a well-formed XML document and we don't care if the repository tag is spread out over multiple lines, or if there is more than one on a line, or what other attributes it has, etc. 请注意,因为现在正在解析XML,我们需要一个格式良好的XML文档,我们不关心存储库标记是分布在多行上,还是一行上有多个,或者其他属性是什么有等等

And it also doesn't fall in to your "regex" tag on your question. 它也不会落入你问题的“正则表达式”标签上。 But that's because I think that tag is making this into an XY problem. 但那是因为我认为该标签正在将其变成XY问题。

I haven't tested, but I believe this will work: 我没有测试过,但我相信这会有效:

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

First, you need to have a group in order to use a backreference, so you have to parenthesize the part of the expression that you want to refer to later. 首先,您需要有一个组才能使用反向引用,因此您必须将表达式的一部分括起来,以便稍后引用。 In this case we want everything from <repository all the way up to enabled... so we enclose that bit in parentheses. 在这种情况下,我们需要从<repository一直到enabled...所有内容enabled...所以我们将该位括在括号中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM