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









share|improve this question




























    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









    share|improve this question


























      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









      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,815824




      3,815824






















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






























            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 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',
              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








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



























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

























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

                  119k16223364




                  119k16223364
























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


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






                      share|improve this answer

























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


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






                        share|improve this answer























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

                          296k54560905




                          296k54560905






























                              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

                              The Sandy Post

                              Danny Elfman

                              Pages that link to "Head v. Amoskeag Manufacturing Co."