Perl command line regex to modify all pattern matches
up vote
5
down vote
favorite
I'm trying to use some arithmetic over the matched patterns in perl command line. I'm able to do it for one match but not for all.
str="a1b2c3"
perl -pe 's/d+/$&+1/e' <<<"$str"
a2b2c3
I understand $& refers to the first matched digit 1 here. What do I need to do to add 1 to all the digits? Is there a variable similar to $& that represents all matched patterns? or the regex needs to be modified to match multiple digits.
For the given input, I'm expecting output something like
a2b3c4
command-line regular-expression perl
add a comment |
up vote
5
down vote
favorite
I'm trying to use some arithmetic over the matched patterns in perl command line. I'm able to do it for one match but not for all.
str="a1b2c3"
perl -pe 's/d+/$&+1/e' <<<"$str"
a2b2c3
I understand $& refers to the first matched digit 1 here. What do I need to do to add 1 to all the digits? Is there a variable similar to $& that represents all matched patterns? or the regex needs to be modified to match multiple digits.
For the given input, I'm expecting output something like
a2b3c4
command-line regular-expression perl
add a comment |
up vote
5
down vote
favorite
up vote
5
down vote
favorite
I'm trying to use some arithmetic over the matched patterns in perl command line. I'm able to do it for one match but not for all.
str="a1b2c3"
perl -pe 's/d+/$&+1/e' <<<"$str"
a2b2c3
I understand $& refers to the first matched digit 1 here. What do I need to do to add 1 to all the digits? Is there a variable similar to $& that represents all matched patterns? or the regex needs to be modified to match multiple digits.
For the given input, I'm expecting output something like
a2b3c4
command-line regular-expression perl
I'm trying to use some arithmetic over the matched patterns in perl command line. I'm able to do it for one match but not for all.
str="a1b2c3"
perl -pe 's/d+/$&+1/e' <<<"$str"
a2b2c3
I understand $& refers to the first matched digit 1 here. What do I need to do to add 1 to all the digits? Is there a variable similar to $& that represents all matched patterns? or the regex needs to be modified to match multiple digits.
For the given input, I'm expecting output something like
a2b3c4
command-line regular-expression perl
command-line regular-expression perl
edited Nov 11 at 12:56
asked Nov 11 at 11:01
Inian
3,815824
3,815824
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
up vote
8
down vote
accepted
str="a1b2c3"
perl -pe 's/d+/$&+1/ge' <<<"$str"
The g flag to the substitution would make Perl apply the expression for each non-overlapping match on the input line.
Nitpick: There are actually no capture groups involved here (the original question mentioned capture groups). The Perl variable $& is the "string matched by the last successful pattern match". This is different from e.g. $1 and $2 etc. that refer to the string matched by the corresponding capture group (parenthesised expression). There are no capture groups in d+, but you could have used s/(d+)/$1+1/ge instead, which does use a single capture group.
There is no difference between s/(d+)/$1+1/ge and s/d+/$&+1/ge in terms of outcome. In this short in-line Perl script, it makes no difference whether you choose to use one or the other, but generally you'd like to avoid using $& in longer Perl programs that do many regular expression operations, at least if using an older Perl release.
From perldoc perlvar (my emphasis):
Performance issues
Traditionally in Perl, any use of any of the three variables
$`,$&or$'
(or theiruse Englishequivalents) anywhere in the code, caused all
subsequent successful pattern matches to make a copy of the matched
string, in case the code might subsequently access one of those variables.
This imposed a considerable performance penalty across the whole program,
so generally the use of these variables has been discouraged.
[...]
In Perl 5.20.0 a new copy-on-write system was enabled by default, which
finally fixes all performance issues with these three variables, and makes
them safe to use anywhere.
add a comment |
up vote
2
down vote
In case you're actually using the zsh shell (<<< is a non-standard operator that does come from zsh, but has been copied to a few other shells since), note that you don't need to invoke perl for that.
You can do:
set -o extendedglob # for (#m) below
printf '%sn' ${str//(#m)<->/$((MATCH+1))}
Where
(#m)turns on the capturing of the whole match in$MATCH(the equivalent ofperl's$&)
<->matches any sequence of decimal digits (it's like<5-12>but without any bound).
add a comment |
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
8
down vote
accepted
str="a1b2c3"
perl -pe 's/d+/$&+1/ge' <<<"$str"
The g flag to the substitution would make Perl apply the expression for each non-overlapping match on the input line.
Nitpick: There are actually no capture groups involved here (the original question mentioned capture groups). The Perl variable $& is the "string matched by the last successful pattern match". This is different from e.g. $1 and $2 etc. that refer to the string matched by the corresponding capture group (parenthesised expression). There are no capture groups in d+, but you could have used s/(d+)/$1+1/ge instead, which does use a single capture group.
There is no difference between s/(d+)/$1+1/ge and s/d+/$&+1/ge in terms of outcome. In this short in-line Perl script, it makes no difference whether you choose to use one or the other, but generally you'd like to avoid using $& in longer Perl programs that do many regular expression operations, at least if using an older Perl release.
From perldoc perlvar (my emphasis):
Performance issues
Traditionally in Perl, any use of any of the three variables
$`,$&or$'
(or theiruse Englishequivalents) anywhere in the code, caused all
subsequent successful pattern matches to make a copy of the matched
string, in case the code might subsequently access one of those variables.
This imposed a considerable performance penalty across the whole program,
so generally the use of these variables has been discouraged.
[...]
In Perl 5.20.0 a new copy-on-write system was enabled by default, which
finally fixes all performance issues with these three variables, and makes
them safe to use anywhere.
add a comment |
up vote
8
down vote
accepted
str="a1b2c3"
perl -pe 's/d+/$&+1/ge' <<<"$str"
The g flag to the substitution would make Perl apply the expression for each non-overlapping match on the input line.
Nitpick: There are actually no capture groups involved here (the original question mentioned capture groups). The Perl variable $& is the "string matched by the last successful pattern match". This is different from e.g. $1 and $2 etc. that refer to the string matched by the corresponding capture group (parenthesised expression). There are no capture groups in d+, but you could have used s/(d+)/$1+1/ge instead, which does use a single capture group.
There is no difference between s/(d+)/$1+1/ge and s/d+/$&+1/ge in terms of outcome. In this short in-line Perl script, it makes no difference whether you choose to use one or the other, but generally you'd like to avoid using $& in longer Perl programs that do many regular expression operations, at least if using an older Perl release.
From perldoc perlvar (my emphasis):
Performance issues
Traditionally in Perl, any use of any of the three variables
$`,$&or$'
(or theiruse Englishequivalents) anywhere in the code, caused all
subsequent successful pattern matches to make a copy of the matched
string, in case the code might subsequently access one of those variables.
This imposed a considerable performance penalty across the whole program,
so generally the use of these variables has been discouraged.
[...]
In Perl 5.20.0 a new copy-on-write system was enabled by default, which
finally fixes all performance issues with these three variables, and makes
them safe to use anywhere.
add a comment |
up vote
8
down vote
accepted
up vote
8
down vote
accepted
str="a1b2c3"
perl -pe 's/d+/$&+1/ge' <<<"$str"
The g flag to the substitution would make Perl apply the expression for each non-overlapping match on the input line.
Nitpick: There are actually no capture groups involved here (the original question mentioned capture groups). The Perl variable $& is the "string matched by the last successful pattern match". This is different from e.g. $1 and $2 etc. that refer to the string matched by the corresponding capture group (parenthesised expression). There are no capture groups in d+, but you could have used s/(d+)/$1+1/ge instead, which does use a single capture group.
There is no difference between s/(d+)/$1+1/ge and s/d+/$&+1/ge in terms of outcome. In this short in-line Perl script, it makes no difference whether you choose to use one or the other, but generally you'd like to avoid using $& in longer Perl programs that do many regular expression operations, at least if using an older Perl release.
From perldoc perlvar (my emphasis):
Performance issues
Traditionally in Perl, any use of any of the three variables
$`,$&or$'
(or theiruse Englishequivalents) anywhere in the code, caused all
subsequent successful pattern matches to make a copy of the matched
string, in case the code might subsequently access one of those variables.
This imposed a considerable performance penalty across the whole program,
so generally the use of these variables has been discouraged.
[...]
In Perl 5.20.0 a new copy-on-write system was enabled by default, which
finally fixes all performance issues with these three variables, and makes
them safe to use anywhere.
str="a1b2c3"
perl -pe 's/d+/$&+1/ge' <<<"$str"
The g flag to the substitution would make Perl apply the expression for each non-overlapping match on the input line.
Nitpick: There are actually no capture groups involved here (the original question mentioned capture groups). The Perl variable $& is the "string matched by the last successful pattern match". This is different from e.g. $1 and $2 etc. that refer to the string matched by the corresponding capture group (parenthesised expression). There are no capture groups in d+, but you could have used s/(d+)/$1+1/ge instead, which does use a single capture group.
There is no difference between s/(d+)/$1+1/ge and s/d+/$&+1/ge in terms of outcome. In this short in-line Perl script, it makes no difference whether you choose to use one or the other, but generally you'd like to avoid using $& in longer Perl programs that do many regular expression operations, at least if using an older Perl release.
From perldoc perlvar (my emphasis):
Performance issues
Traditionally in Perl, any use of any of the three variables
$`,$&or$'
(or theiruse Englishequivalents) anywhere in the code, caused all
subsequent successful pattern matches to make a copy of the matched
string, in case the code might subsequently access one of those variables.
This imposed a considerable performance penalty across the whole program,
so generally the use of these variables has been discouraged.
[...]
In Perl 5.20.0 a new copy-on-write system was enabled by default, which
finally fixes all performance issues with these three variables, and makes
them safe to use anywhere.
edited Nov 11 at 17:11
answered Nov 11 at 11:25
Kusalananda
119k16223364
119k16223364
add a comment |
add a comment |
up vote
2
down vote
In case you're actually using the zsh shell (<<< is a non-standard operator that does come from zsh, but has been copied to a few other shells since), note that you don't need to invoke perl for that.
You can do:
set -o extendedglob # for (#m) below
printf '%sn' ${str//(#m)<->/$((MATCH+1))}
Where
(#m)turns on the capturing of the whole match in$MATCH(the equivalent ofperl's$&)
<->matches any sequence of decimal digits (it's like<5-12>but without any bound).
add a comment |
up vote
2
down vote
In case you're actually using the zsh shell (<<< is a non-standard operator that does come from zsh, but has been copied to a few other shells since), note that you don't need to invoke perl for that.
You can do:
set -o extendedglob # for (#m) below
printf '%sn' ${str//(#m)<->/$((MATCH+1))}
Where
(#m)turns on the capturing of the whole match in$MATCH(the equivalent ofperl's$&)
<->matches any sequence of decimal digits (it's like<5-12>but without any bound).
add a comment |
up vote
2
down vote
up vote
2
down vote
In case you're actually using the zsh shell (<<< is a non-standard operator that does come from zsh, but has been copied to a few other shells since), note that you don't need to invoke perl for that.
You can do:
set -o extendedglob # for (#m) below
printf '%sn' ${str//(#m)<->/$((MATCH+1))}
Where
(#m)turns on the capturing of the whole match in$MATCH(the equivalent ofperl's$&)
<->matches any sequence of decimal digits (it's like<5-12>but without any bound).
In case you're actually using the zsh shell (<<< is a non-standard operator that does come from zsh, but has been copied to a few other shells since), note that you don't need to invoke perl for that.
You can do:
set -o extendedglob # for (#m) below
printf '%sn' ${str//(#m)<->/$((MATCH+1))}
Where
(#m)turns on the capturing of the whole match in$MATCH(the equivalent ofperl's$&)
<->matches any sequence of decimal digits (it's like<5-12>but without any bound).
answered Nov 11 at 13:04
Stéphane Chazelas
296k54560905
296k54560905
add a comment |
add a comment |
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f481073%2fperl-command-line-regex-to-modify-all-pattern-matches%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown