Reputation: 113
I seek your wisdom on this regex that's driving me crazy.
I want to replace the second underscore with a colon. That's it.
So far:
my $str = "bythepower_of_grayskull";
$str =~ s/.*?_.*?(_)/:/g;
print "$str\n";
Current output: :grayskull
Desired output: bythepower_of:grayskull
Upvotes: 1
Views: 1572
Reputation: 89639
Don't use the g modifier for only one replacement:
$str =~ s/_[^_]*\K_/:/;
Upvotes: 1
Reputation:
You can capture occurrence of first underscore + some string
and then second underscore
and replace accordingly.
Regex: (_.*?)_
Explanation:
(_.*)
matches the first underscore and some string.
(_)
matches the second underscore.
Replacement to do: Replace with \1:
Regex: _([^_]*$)
Explanation: As your string have only two underscore this regex will capture the first one from end of string.
_
matches first underscore from end of string. ( Second from beginning.)
([^_]*$)
matches rest of the string till end.
Replacement to do: Replace with :\1
You can also use positive lookahead
. This is a little modification over Solution #2
. Only thing you have to do here is lookahead for rest of the string
instead of capturing it.
Regex: _(?=[^_]*$)
Explanation:
_
matches the underscore after it looksahead that no underscores are present till end of string. Thus mathematically second underscore will be matched.Replacement to do: Replace with :
.
Upvotes: 1
Reputation: 782683
You need to put the capture group around the part that you want to keep, not the part you want to replace. Then use $1
in the replacement to copy the captured text.
$str =~ s/(.*?_.*?)_/$1:/;
And if there are only 2 underscores, you don't need the g
modifier, since there's only one replacement being done.
Upvotes: 2