I need to find and replace a word or expression in a file with my own, of course. For example, I have a file file.xml :

 <title name="Article">Article</title> <title name="article_1">text Article text</title> 

I need to replace the word Article just inside the brackets >< . I tried working with perl via cmd :

 perl -p -i -e "s/article/myText/gi" file.xml 

but when writing a replacement expression with regular expressions, it turns out that not one word is replaced, but all that I have indicated. I need to replace only one word - article .

  • The example you gave replaces the word article (in small letters). Explain the problem in more detail - Mike
  • I need to replace the word article with any register (corrected post) by mask. If you put the mask in parentheses, something like s/\s*>\s*article\s*<\s* , then the whole mask is replaced, and I need to replace only one word. - Sergey Molyak
  • apparently that from the type \s*>\s*\Karticle(?=\s*<\s*) ? only the letter i added after g that it would be case insensitive - Mike
  • Good. In this way, I get the string <title name="Article"myText/title> instead of the desired <title name="Article">myText</title> - Sergey Molyak
  • Look in the direction of variables that store matches with each part of the pattern: $ 1, $ 2, ... - DimXenon

3 answers 3

 perl -p -i -e 's/(\G|>)[^<>]*?\Karticle/myText/gi' file.xml 

\G - denotes the entry point to the expression after the last replacement. Thus (\G|>) will search for the subsequent text immediately after the end of the tag and after the replacement made, will continue to search for the same text from the point where this replacement occurred. \K - denotes the point, the entire expression to which is considered a preliminary check in the very match for the replacement is not included.

Regex101.com example

    For example:

     #!/usr/bin/env perl use Modern::Perl; use Data::Printer; use XML::Simple; my $xml = XMLin( 'data.xml' ); p $xml; replace_content( $xml, 'article', 'myText' ); p $xml; say XMLout( $xml ); sub replace_content { my ($xml, $what, $to) = @_; # доп. проверки пропущены для наглядности if( ref $xml eq 'HASH' ) { $xml->{content} =~ s/$what/$to/igs if $xml->{content}; replace_content( $xml->{$_}, $what, $to ) for keys $xml; } } 

    NB! The output of XMLout() may differ from the original. If this is critical, you can play around with the keys (see the documentation , the question " XML :: Simple, output the same XML as input , etc.).

       perl -in -p -e "s!>article<!>word<!igs" file.xml 
      • Try to write more detailed answers. Explain what is the basis of your statement? - Nicolas Chabanovsky
      • on reading the manual - user219142