user2585000
user2585000

Reputation: 113

Perl regex: find second underscore and replace with a colon within a string

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

Answers (4)

Borodin
Borodin

Reputation: 126772

All you need is

$str =~ s/.*\K_/:/;

Upvotes: 2

Casimir et Hippolyte
Casimir et Hippolyte

Reputation: 89639

Don't use the g modifier for only one replacement:

$str =~ s/_[^_]*\K_/:/;

Upvotes: 1

user2705585
user2705585

Reputation:

You can capture occurrence of first underscore + some string and then second underscore and replace accordingly.

Solution #1

Regex: (_.*?)_

Explanation:

  • (_.*) matches the first underscore and some string.

  • (_) matches the second underscore.

Replacement to do: Replace with \1:

Regex101 Demo


Solution #2

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

Regex101 Demo


Solution #3

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 :.

Regex101 Demo

Upvotes: 1

Barmar
Barmar

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

Related Questions