susdu
susdu

Reputation: 862

perl increment number in string with evaluation modifier

I'm trying to increment:

Text_1_string(0)

to

Text_1_string(1)

and so on. Note that I only want to increment the number in the parenthesis. I've used:

name =~ s/\(([0-9]+)\)/$1 + 1/e;

but it turns out as:

Text_1_string1

and I don't understand why. The group captured is the number, it shouldn't replace the parenthesis.

Upvotes: 1

Views: 80

Answers (1)

zdim
zdim

Reputation: 66881

It replaces the whole pattern that it matched, not only what is also captured. So you do need to put back the parens

$name =~ s/\(([0-9]+)\)/'('.($1 + 1).')'/e;

Since the replacement part is evaluated as code it need be normal Perl code, thus the quotes and concatenation, and parenthesis for precedence.


To add, there are patterns that need not be put back in the replacement part: lookahead and lookbehind assertions. Like common anchors, these are zero width assertions, so they do not consume what they match -- you only "look"

$name =~ s/(?<=\() ([0-9]+) (?=\))/$1 + 1/xe;

The lookbehind can't be of variable length (like \w+); it takes only a fixed string pattern.

The (?<=...) asserts that the (fixed length) pattern in parenthesis (which do not capture!) must precede the number while (?=...) asserts that the pattern in its parens must follow, for the whole pattern to match.

Often very useful is the lookbehind-type construct \K, which makes the engine keep in the string what it had matched up to that point (instead of "consuming" it); so it "drops" previous matches, much like the (?<=...) form

$name =~ s/\(\K ([0-9]+) (?=\))/$1 + 1/xe;

This is also more efficient. While it is also termed a "lookbehind" in documentation, there are in fact distinct differences in behavior. See this post and comments. Thanks to ikegami for a comment.

All these are positive lookarounds; there are also negative ones, asserting that given patterns must not be there for the whole thing to match.

A bit of an overkill in this case but a true gift in some other cases.

Upvotes: 1

Related Questions