Perl: How to replace only the matched part of a string?

I have a line foo_bar_not_needed_string_part_123 . Now on this line I want to remove not_needed_string_part only when foo_ follows bar .

I used the following regular expression:

 my $str = "foo_bar_not_needed_string_part_123"; say $str if $str =~ s/foo_(?=bar)bar_(.*?)_\d+//; 

But he deleted the whole line and just prints a new line.

So, I need to remove only the matching (. *?) Part. So, the way out

 foo_bar__123. 
+4
source share
7 answers

There's a different way, and it's pretty simple:

 my $str = "foo_bar_not_needed_string_part_123"; $str =~ s/(?<=foo_bar_)\D+//gi; print $str; 

The trick is to use the checkbehind check anchor and replace all non-digital characters that follow this anchor (and not the character). Basically, with this pattern you map only the characters that you want to delete, so there is no need to capture groups.

As a side element in the original construct, regex (?=bar)bar redundant. The first part (lookahead) will correspond only if a certain position is followed by "bar", but exactly what was checked using the unglazed part of the template.

+4
source

You can capture parts that you do not want to delete:

 my $str = "foo_bar_not_needed_string_part_123"; $str =~ s/(foo_bar_).*?(_\d+)/$1$2/; print $str; 
+2
source

You can try the following:

 my $str = "foo_bar_not_needed_string_part_123"; say $str if $str =~ s/(foo_(?=bar)bar_).*?(_\d+)/$1$2/; 

Outputs:

foo_bar__123

PS: I am new to perl/regex , so I am wondering if there is a way to directly replace the agreed part. What I did was grab everything that was required and replace it with the whole line.

+1
source

How to split a string into 3 parts and delete only the middle one?

 $str =~ s/(foo_(?=bar)bar_)(.*?)(_\d+)/$1$3/; 
+1
source

Try the following:

 (?<=foo_bar_).*(?=_\d) 

In this option, it includes the result of ALL ( .* ) Between foo_bar_ and _"any digit" .

In your regular expression, it includes the result:

 foo_ 

He then searches for "bar" after "foo _":

 (?=bar) 

But at this stage it is not turned on. It is included in the next step:

 bar_ 

And then the rest of the line is included (.*?)_\d+ .

So, in general: it includes in the result all of this that you typed, EXCEPT (? = Bar), which simply searches for "bar" after the expression.

+1
source

go with

 echo "foo_bar_not_needed_string_part_123" | perl -pe 's/(?<=foo_bar_)[^\d]+//' 
+1
source

In this case, you can use look-behind / look-ahead

 $str =~ s/(?<=foo_bar_).*?(?=_\d+)//; 

and the look can be replaced with \K (save) to make it a little neater

 $str =~ s/foo_bar_\K.*?(?=_\d+)//; 
+1
source

Source: https://habr.com/ru/post/1434445/


All Articles