Perl command line regex to modify all pattern matches
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 |
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 |
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,860824
3,860824
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
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 |
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 |
Your Answer
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "106"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
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
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
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 |
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 |
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
121k16229372
121k16229372
add a comment |
add a comment |
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 |
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 |
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
299k54563913
299k54563913
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