Как использовать переменные замены при выполнении поиска / замены с помощью Regex в Perl? - PullRequest
0 голосов
/ 06 октября 2011

Я хочу найти в xml-файле все теги-теги, меняя атрибут enable на false, что может быть следующим:

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

Есть и другие теги, имеющие атрибут enabled, поэтому мне нужнопоиск строк, начинающихся с, что довольно просто, проблема в замене строки.Я пробовал это:

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

Но не повезло, в файл не вносятся изменения, которые я пытаюсь изменить.Или, это не правда, это соответствует, но я не могу изменить ТОЛЬКО enabled = "true", устанавливая его в false, он удаляет оставшуюся часть строки, оставляя его просто enabled = "false" ...

Должно быть возможно согласно http://refcards.com/docs/trusketti/perl-regexp/perl-regexp-refcard-a4.pdf

Ответы [ 2 ]

4 голосов
/ 06 октября 2011
#!/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();

Кажется, работает на меня. Возможно, вы захотите поиграть с обратным вызовом для тега хранилища - я не уверен, хотите ли вы всегда устанавливать для включенного атрибута значение false, даже если атрибут отсутствует (удалить первую строку в этом обратном вызове) или только если атрибут есть.

Хорошо, это больше не однострочник. Но это не должно быть требованием, если вы хотите, чтобы все было сделано правильно. Обратите внимание, что поскольку сейчас выполняется синтаксический анализ XML, нам необходим правильно сформированный XML-документ, и нам все равно, будет ли тег репозитория разбит на несколько строк, или если в строке будет более одного тега, или какие другие атрибуты будут у него имеет и т.д.

И это также не относится к вашему тегу "regex" в вашем вопросе. Но это потому, что я думаю, что этот тег превращает это в проблему XY.

0 голосов
/ 06 октября 2011

Я не проверял, но я считаю, что это будет работать:

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

Во-первых, вам нужна группа, чтобы использовать обратную ссылку, поэтому вы должны заключить часть выражения в скобкичто вы хотите сослаться позже.В этом случае мы хотим, чтобы все от <repository до enabled..., поэтому мы заключаем этот бит в скобки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...