Perl command line regex to modify all pattern matches










5














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









share|improve this question




























    5














    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









    share|improve this question


























      5












      5








      5







      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









      share|improve this question















      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






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 11 at 12:56

























      asked Nov 11 at 11:01









      Inian

      3,860824




      3,860824




















          2 Answers
          2






          active

          oldest

          votes


















          8














          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 their use English equivalents) 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.







          share|improve this answer






























            2














            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 of perl's $&)


            • <-> matches any sequence of decimal digits (it's like <5-12> but without any bound).





            share|improve this answer




















              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
              );



              );













              draft saved

              draft discarded


















              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









              8














              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 their use English equivalents) 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.







              share|improve this answer



























                8














                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 their use English equivalents) 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.







                share|improve this answer

























                  8












                  8








                  8






                  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 their use English equivalents) 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.







                  share|improve this answer














                  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 their use English equivalents) 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.








                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Nov 11 at 17:11

























                  answered Nov 11 at 11:25









                  Kusalananda

                  121k16229372




                  121k16229372























                      2














                      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 of perl's $&)


                      • <-> matches any sequence of decimal digits (it's like <5-12> but without any bound).





                      share|improve this answer

























                        2














                        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 of perl's $&)


                        • <-> matches any sequence of decimal digits (it's like <5-12> but without any bound).





                        share|improve this answer























                          2












                          2








                          2






                          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 of perl's $&)


                          • <-> matches any sequence of decimal digits (it's like <5-12> but without any bound).





                          share|improve this answer












                          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 of perl's $&)


                          • <-> matches any sequence of decimal digits (it's like <5-12> but without any bound).






                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered Nov 11 at 13:04









                          Stéphane Chazelas

                          299k54563913




                          299k54563913



























                              draft saved

                              draft discarded
















































                              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.




                              draft saved


                              draft discarded














                              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





















































                              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







                              Popular posts from this blog

                              Kleinkühnau

                              Makov (Slowakei)

                              Deutsches Schauspielhaus