How to write regexp literal in match expression?











up vote
2
down vote

favorite
1












This question is about the proper way to write regular expression literals in a match expression under bash.



In zsh, the match below succeeds, as I expected:



% [[ ' 123 ' =~ '^ [0-9]+ $' ]]; echo $?
0


Not so in bash:



$ [[ ' 123 ' =~ '^ [0-9]+ $' ]]; echo $?
1


I know that this match succeeds in bash



$ ( regexp='^ [0-9]+ $'; [[ ' 123 ' =~ $regexp ]]; echo $? )
0


...but it requires assigning the regular expression to an intermediate variable.





My question is: How does one write an arbitrary regular expression literal in a match expression under bash?










share|improve this question


























    up vote
    2
    down vote

    favorite
    1












    This question is about the proper way to write regular expression literals in a match expression under bash.



    In zsh, the match below succeeds, as I expected:



    % [[ ' 123 ' =~ '^ [0-9]+ $' ]]; echo $?
    0


    Not so in bash:



    $ [[ ' 123 ' =~ '^ [0-9]+ $' ]]; echo $?
    1


    I know that this match succeeds in bash



    $ ( regexp='^ [0-9]+ $'; [[ ' 123 ' =~ $regexp ]]; echo $? )
    0


    ...but it requires assigning the regular expression to an intermediate variable.





    My question is: How does one write an arbitrary regular expression literal in a match expression under bash?










    share|improve this question
























      up vote
      2
      down vote

      favorite
      1









      up vote
      2
      down vote

      favorite
      1






      1





      This question is about the proper way to write regular expression literals in a match expression under bash.



      In zsh, the match below succeeds, as I expected:



      % [[ ' 123 ' =~ '^ [0-9]+ $' ]]; echo $?
      0


      Not so in bash:



      $ [[ ' 123 ' =~ '^ [0-9]+ $' ]]; echo $?
      1


      I know that this match succeeds in bash



      $ ( regexp='^ [0-9]+ $'; [[ ' 123 ' =~ $regexp ]]; echo $? )
      0


      ...but it requires assigning the regular expression to an intermediate variable.





      My question is: How does one write an arbitrary regular expression literal in a match expression under bash?










      share|improve this question













      This question is about the proper way to write regular expression literals in a match expression under bash.



      In zsh, the match below succeeds, as I expected:



      % [[ ' 123 ' =~ '^ [0-9]+ $' ]]; echo $?
      0


      Not so in bash:



      $ [[ ' 123 ' =~ '^ [0-9]+ $' ]]; echo $?
      1


      I know that this match succeeds in bash



      $ ( regexp='^ [0-9]+ $'; [[ ' 123 ' =~ $regexp ]]; echo $? )
      0


      ...but it requires assigning the regular expression to an intermediate variable.





      My question is: How does one write an arbitrary regular expression literal in a match expression under bash?







      bash shell-script scripting regular-expression syntax






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 21 at 20:09









      kjo

      4,01893663




      4,01893663






















          2 Answers
          2






          active

          oldest

          votes

















          up vote
          6
          down vote



          accepted










          It's best to put it in a variable, as recommended by the Bash reference manual 3.2.4.2 Conditional Constructs:




          Storing the regular expression in a shell variable is often a useful way to avoid problems with quoting characters that are special to the shell. It is sometimes difficult to specify a regular expression literally without using quotes, or to keep track of the quoting used by regular expressions while paying attention to the shell’s quote removal. Using a shell variable to store the pattern decreases these problems.




          However in order to write it directly inside of the bash extended test you need to remove the quotes and escape the spaces:



          $ [[ ' 123 ' =~ ^ [0-9]+ $ ]]; echo $?
          0





          share|improve this answer




























            up vote
            2
            down vote













            In bash, the canonical answer is: use a var



            $ reg='^ [0-9]+ $'
            $ [[ ' 123 ' =~ $reg ]]; echo $?


            That works for spaces, backslash, and many other things:



            $ reg='^ 123 $'
            $ [[ ' 123 ' =~ $reg ]]; echo $?
            0


            If you want to write it as a literal you need to play (carefully) with quoting.

            You need to quote the parts that need to be literal and leave the parts that should be interpreted as a regex un-quoted. The space needs quoting. Here using backslah:



            $ [[ ' 123 ' =~ ^ [0-9]+ $ ]]; echo $?
            0


            And here using double quotes:



            $ [[ ' 123 ' =~ ^" "[0-9]+" "$ ]]; echo $?


            But that "quoting" gets real messy with things like a backslash:



            $ [[ ' 123 ' =~ ^" "[0-9]+"\"[0-9]+" "$ ]]; echo $?
            0


            Simpler, safer:



            $ reg='^ [0-9]+\[0-9]+ $'
            $ [[ ' 123 ' =~ $reg ]]; echo $?
            0


            And, no, you don't need a subshell to do that (the parenthesis in your question).



            $ reg='^ [0-9]+\[0-9]+ $'; [[ ' 123 ' =~ $reg ]]; echo $?




            Yes, that may seem annoying.
            And, yes, the command you presented happens to work in zsh:



            $ [[ ' 123 ' =~ '^ [0-9]+ $' ]]; echo $?
            0


            But quoting is always a problem (in any shell), what should happen to backslash ?:



            % [[ ' 123 ' =~ ' 123 ' ]]; echo $?
            zsh: failed to compile regex: Invalid back reference
            1


            % [[ ' 123 ' =~ '^ [0-9]+\3 $' ]]; echo $?
            0


            Double it !. It is not exactly: literal.






            share|improve this answer























            • I know that the subshell is not needed for the match; I use subshells to avoid polluting my current shell's namespace with a variable that I need to use only once.
              – kjo
              Nov 21 at 21:08












            • An unset regexp is always faster than a subshell. @kjo
              – Isaac
              Nov 21 at 23:12










            • Maybe, but I don't care about the few milliseconds here and there. The subshell takes fewer keystrokes, it is robust to any number of changes I may do in the subshell (not just the setting of one variable), and there's no chance I will forget to run unset afterwards.
              – kjo
              Nov 22 at 16:54












            • Sure, why fight the waste if it is easier?. Why reduce the use of plastics until we get a plastic planet? @kjo
              – Isaac
              Nov 23 at 0:49










            • Thanks, you made me laugh.
              – kjo
              Nov 23 at 0:56











            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%2f483292%2fhow-to-write-regexp-literal-in-match-expression%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
            6
            down vote



            accepted










            It's best to put it in a variable, as recommended by the Bash reference manual 3.2.4.2 Conditional Constructs:




            Storing the regular expression in a shell variable is often a useful way to avoid problems with quoting characters that are special to the shell. It is sometimes difficult to specify a regular expression literally without using quotes, or to keep track of the quoting used by regular expressions while paying attention to the shell’s quote removal. Using a shell variable to store the pattern decreases these problems.




            However in order to write it directly inside of the bash extended test you need to remove the quotes and escape the spaces:



            $ [[ ' 123 ' =~ ^ [0-9]+ $ ]]; echo $?
            0





            share|improve this answer

























              up vote
              6
              down vote



              accepted










              It's best to put it in a variable, as recommended by the Bash reference manual 3.2.4.2 Conditional Constructs:




              Storing the regular expression in a shell variable is often a useful way to avoid problems with quoting characters that are special to the shell. It is sometimes difficult to specify a regular expression literally without using quotes, or to keep track of the quoting used by regular expressions while paying attention to the shell’s quote removal. Using a shell variable to store the pattern decreases these problems.




              However in order to write it directly inside of the bash extended test you need to remove the quotes and escape the spaces:



              $ [[ ' 123 ' =~ ^ [0-9]+ $ ]]; echo $?
              0





              share|improve this answer























                up vote
                6
                down vote



                accepted







                up vote
                6
                down vote



                accepted






                It's best to put it in a variable, as recommended by the Bash reference manual 3.2.4.2 Conditional Constructs:




                Storing the regular expression in a shell variable is often a useful way to avoid problems with quoting characters that are special to the shell. It is sometimes difficult to specify a regular expression literally without using quotes, or to keep track of the quoting used by regular expressions while paying attention to the shell’s quote removal. Using a shell variable to store the pattern decreases these problems.




                However in order to write it directly inside of the bash extended test you need to remove the quotes and escape the spaces:



                $ [[ ' 123 ' =~ ^ [0-9]+ $ ]]; echo $?
                0





                share|improve this answer












                It's best to put it in a variable, as recommended by the Bash reference manual 3.2.4.2 Conditional Constructs:




                Storing the regular expression in a shell variable is often a useful way to avoid problems with quoting characters that are special to the shell. It is sometimes difficult to specify a regular expression literally without using quotes, or to keep track of the quoting used by regular expressions while paying attention to the shell’s quote removal. Using a shell variable to store the pattern decreases these problems.




                However in order to write it directly inside of the bash extended test you need to remove the quotes and escape the spaces:



                $ [[ ' 123 ' =~ ^ [0-9]+ $ ]]; echo $?
                0






                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 21 at 20:21









                Jesse_b

                11.4k23063




                11.4k23063
























                    up vote
                    2
                    down vote













                    In bash, the canonical answer is: use a var



                    $ reg='^ [0-9]+ $'
                    $ [[ ' 123 ' =~ $reg ]]; echo $?


                    That works for spaces, backslash, and many other things:



                    $ reg='^ 123 $'
                    $ [[ ' 123 ' =~ $reg ]]; echo $?
                    0


                    If you want to write it as a literal you need to play (carefully) with quoting.

                    You need to quote the parts that need to be literal and leave the parts that should be interpreted as a regex un-quoted. The space needs quoting. Here using backslah:



                    $ [[ ' 123 ' =~ ^ [0-9]+ $ ]]; echo $?
                    0


                    And here using double quotes:



                    $ [[ ' 123 ' =~ ^" "[0-9]+" "$ ]]; echo $?


                    But that "quoting" gets real messy with things like a backslash:



                    $ [[ ' 123 ' =~ ^" "[0-9]+"\"[0-9]+" "$ ]]; echo $?
                    0


                    Simpler, safer:



                    $ reg='^ [0-9]+\[0-9]+ $'
                    $ [[ ' 123 ' =~ $reg ]]; echo $?
                    0


                    And, no, you don't need a subshell to do that (the parenthesis in your question).



                    $ reg='^ [0-9]+\[0-9]+ $'; [[ ' 123 ' =~ $reg ]]; echo $?




                    Yes, that may seem annoying.
                    And, yes, the command you presented happens to work in zsh:



                    $ [[ ' 123 ' =~ '^ [0-9]+ $' ]]; echo $?
                    0


                    But quoting is always a problem (in any shell), what should happen to backslash ?:



                    % [[ ' 123 ' =~ ' 123 ' ]]; echo $?
                    zsh: failed to compile regex: Invalid back reference
                    1


                    % [[ ' 123 ' =~ '^ [0-9]+\3 $' ]]; echo $?
                    0


                    Double it !. It is not exactly: literal.






                    share|improve this answer























                    • I know that the subshell is not needed for the match; I use subshells to avoid polluting my current shell's namespace with a variable that I need to use only once.
                      – kjo
                      Nov 21 at 21:08












                    • An unset regexp is always faster than a subshell. @kjo
                      – Isaac
                      Nov 21 at 23:12










                    • Maybe, but I don't care about the few milliseconds here and there. The subshell takes fewer keystrokes, it is robust to any number of changes I may do in the subshell (not just the setting of one variable), and there's no chance I will forget to run unset afterwards.
                      – kjo
                      Nov 22 at 16:54












                    • Sure, why fight the waste if it is easier?. Why reduce the use of plastics until we get a plastic planet? @kjo
                      – Isaac
                      Nov 23 at 0:49










                    • Thanks, you made me laugh.
                      – kjo
                      Nov 23 at 0:56















                    up vote
                    2
                    down vote













                    In bash, the canonical answer is: use a var



                    $ reg='^ [0-9]+ $'
                    $ [[ ' 123 ' =~ $reg ]]; echo $?


                    That works for spaces, backslash, and many other things:



                    $ reg='^ 123 $'
                    $ [[ ' 123 ' =~ $reg ]]; echo $?
                    0


                    If you want to write it as a literal you need to play (carefully) with quoting.

                    You need to quote the parts that need to be literal and leave the parts that should be interpreted as a regex un-quoted. The space needs quoting. Here using backslah:



                    $ [[ ' 123 ' =~ ^ [0-9]+ $ ]]; echo $?
                    0


                    And here using double quotes:



                    $ [[ ' 123 ' =~ ^" "[0-9]+" "$ ]]; echo $?


                    But that "quoting" gets real messy with things like a backslash:



                    $ [[ ' 123 ' =~ ^" "[0-9]+"\"[0-9]+" "$ ]]; echo $?
                    0


                    Simpler, safer:



                    $ reg='^ [0-9]+\[0-9]+ $'
                    $ [[ ' 123 ' =~ $reg ]]; echo $?
                    0


                    And, no, you don't need a subshell to do that (the parenthesis in your question).



                    $ reg='^ [0-9]+\[0-9]+ $'; [[ ' 123 ' =~ $reg ]]; echo $?




                    Yes, that may seem annoying.
                    And, yes, the command you presented happens to work in zsh:



                    $ [[ ' 123 ' =~ '^ [0-9]+ $' ]]; echo $?
                    0


                    But quoting is always a problem (in any shell), what should happen to backslash ?:



                    % [[ ' 123 ' =~ ' 123 ' ]]; echo $?
                    zsh: failed to compile regex: Invalid back reference
                    1


                    % [[ ' 123 ' =~ '^ [0-9]+\3 $' ]]; echo $?
                    0


                    Double it !. It is not exactly: literal.






                    share|improve this answer























                    • I know that the subshell is not needed for the match; I use subshells to avoid polluting my current shell's namespace with a variable that I need to use only once.
                      – kjo
                      Nov 21 at 21:08












                    • An unset regexp is always faster than a subshell. @kjo
                      – Isaac
                      Nov 21 at 23:12










                    • Maybe, but I don't care about the few milliseconds here and there. The subshell takes fewer keystrokes, it is robust to any number of changes I may do in the subshell (not just the setting of one variable), and there's no chance I will forget to run unset afterwards.
                      – kjo
                      Nov 22 at 16:54












                    • Sure, why fight the waste if it is easier?. Why reduce the use of plastics until we get a plastic planet? @kjo
                      – Isaac
                      Nov 23 at 0:49










                    • Thanks, you made me laugh.
                      – kjo
                      Nov 23 at 0:56













                    up vote
                    2
                    down vote










                    up vote
                    2
                    down vote









                    In bash, the canonical answer is: use a var



                    $ reg='^ [0-9]+ $'
                    $ [[ ' 123 ' =~ $reg ]]; echo $?


                    That works for spaces, backslash, and many other things:



                    $ reg='^ 123 $'
                    $ [[ ' 123 ' =~ $reg ]]; echo $?
                    0


                    If you want to write it as a literal you need to play (carefully) with quoting.

                    You need to quote the parts that need to be literal and leave the parts that should be interpreted as a regex un-quoted. The space needs quoting. Here using backslah:



                    $ [[ ' 123 ' =~ ^ [0-9]+ $ ]]; echo $?
                    0


                    And here using double quotes:



                    $ [[ ' 123 ' =~ ^" "[0-9]+" "$ ]]; echo $?


                    But that "quoting" gets real messy with things like a backslash:



                    $ [[ ' 123 ' =~ ^" "[0-9]+"\"[0-9]+" "$ ]]; echo $?
                    0


                    Simpler, safer:



                    $ reg='^ [0-9]+\[0-9]+ $'
                    $ [[ ' 123 ' =~ $reg ]]; echo $?
                    0


                    And, no, you don't need a subshell to do that (the parenthesis in your question).



                    $ reg='^ [0-9]+\[0-9]+ $'; [[ ' 123 ' =~ $reg ]]; echo $?




                    Yes, that may seem annoying.
                    And, yes, the command you presented happens to work in zsh:



                    $ [[ ' 123 ' =~ '^ [0-9]+ $' ]]; echo $?
                    0


                    But quoting is always a problem (in any shell), what should happen to backslash ?:



                    % [[ ' 123 ' =~ ' 123 ' ]]; echo $?
                    zsh: failed to compile regex: Invalid back reference
                    1


                    % [[ ' 123 ' =~ '^ [0-9]+\3 $' ]]; echo $?
                    0


                    Double it !. It is not exactly: literal.






                    share|improve this answer














                    In bash, the canonical answer is: use a var



                    $ reg='^ [0-9]+ $'
                    $ [[ ' 123 ' =~ $reg ]]; echo $?


                    That works for spaces, backslash, and many other things:



                    $ reg='^ 123 $'
                    $ [[ ' 123 ' =~ $reg ]]; echo $?
                    0


                    If you want to write it as a literal you need to play (carefully) with quoting.

                    You need to quote the parts that need to be literal and leave the parts that should be interpreted as a regex un-quoted. The space needs quoting. Here using backslah:



                    $ [[ ' 123 ' =~ ^ [0-9]+ $ ]]; echo $?
                    0


                    And here using double quotes:



                    $ [[ ' 123 ' =~ ^" "[0-9]+" "$ ]]; echo $?


                    But that "quoting" gets real messy with things like a backslash:



                    $ [[ ' 123 ' =~ ^" "[0-9]+"\"[0-9]+" "$ ]]; echo $?
                    0


                    Simpler, safer:



                    $ reg='^ [0-9]+\[0-9]+ $'
                    $ [[ ' 123 ' =~ $reg ]]; echo $?
                    0


                    And, no, you don't need a subshell to do that (the parenthesis in your question).



                    $ reg='^ [0-9]+\[0-9]+ $'; [[ ' 123 ' =~ $reg ]]; echo $?




                    Yes, that may seem annoying.
                    And, yes, the command you presented happens to work in zsh:



                    $ [[ ' 123 ' =~ '^ [0-9]+ $' ]]; echo $?
                    0


                    But quoting is always a problem (in any shell), what should happen to backslash ?:



                    % [[ ' 123 ' =~ ' 123 ' ]]; echo $?
                    zsh: failed to compile regex: Invalid back reference
                    1


                    % [[ ' 123 ' =~ '^ [0-9]+\3 $' ]]; echo $?
                    0


                    Double it !. It is not exactly: literal.







                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited Nov 21 at 20:40

























                    answered Nov 21 at 20:23









                    Isaac

                    9,70311445




                    9,70311445












                    • I know that the subshell is not needed for the match; I use subshells to avoid polluting my current shell's namespace with a variable that I need to use only once.
                      – kjo
                      Nov 21 at 21:08












                    • An unset regexp is always faster than a subshell. @kjo
                      – Isaac
                      Nov 21 at 23:12










                    • Maybe, but I don't care about the few milliseconds here and there. The subshell takes fewer keystrokes, it is robust to any number of changes I may do in the subshell (not just the setting of one variable), and there's no chance I will forget to run unset afterwards.
                      – kjo
                      Nov 22 at 16:54












                    • Sure, why fight the waste if it is easier?. Why reduce the use of plastics until we get a plastic planet? @kjo
                      – Isaac
                      Nov 23 at 0:49










                    • Thanks, you made me laugh.
                      – kjo
                      Nov 23 at 0:56


















                    • I know that the subshell is not needed for the match; I use subshells to avoid polluting my current shell's namespace with a variable that I need to use only once.
                      – kjo
                      Nov 21 at 21:08












                    • An unset regexp is always faster than a subshell. @kjo
                      – Isaac
                      Nov 21 at 23:12










                    • Maybe, but I don't care about the few milliseconds here and there. The subshell takes fewer keystrokes, it is robust to any number of changes I may do in the subshell (not just the setting of one variable), and there's no chance I will forget to run unset afterwards.
                      – kjo
                      Nov 22 at 16:54












                    • Sure, why fight the waste if it is easier?. Why reduce the use of plastics until we get a plastic planet? @kjo
                      – Isaac
                      Nov 23 at 0:49










                    • Thanks, you made me laugh.
                      – kjo
                      Nov 23 at 0:56
















                    I know that the subshell is not needed for the match; I use subshells to avoid polluting my current shell's namespace with a variable that I need to use only once.
                    – kjo
                    Nov 21 at 21:08






                    I know that the subshell is not needed for the match; I use subshells to avoid polluting my current shell's namespace with a variable that I need to use only once.
                    – kjo
                    Nov 21 at 21:08














                    An unset regexp is always faster than a subshell. @kjo
                    – Isaac
                    Nov 21 at 23:12




                    An unset regexp is always faster than a subshell. @kjo
                    – Isaac
                    Nov 21 at 23:12












                    Maybe, but I don't care about the few milliseconds here and there. The subshell takes fewer keystrokes, it is robust to any number of changes I may do in the subshell (not just the setting of one variable), and there's no chance I will forget to run unset afterwards.
                    – kjo
                    Nov 22 at 16:54






                    Maybe, but I don't care about the few milliseconds here and there. The subshell takes fewer keystrokes, it is robust to any number of changes I may do in the subshell (not just the setting of one variable), and there's no chance I will forget to run unset afterwards.
                    – kjo
                    Nov 22 at 16:54














                    Sure, why fight the waste if it is easier?. Why reduce the use of plastics until we get a plastic planet? @kjo
                    – Isaac
                    Nov 23 at 0:49




                    Sure, why fight the waste if it is easier?. Why reduce the use of plastics until we get a plastic planet? @kjo
                    – Isaac
                    Nov 23 at 0:49












                    Thanks, you made me laugh.
                    – kjo
                    Nov 23 at 0:56




                    Thanks, you made me laugh.
                    – kjo
                    Nov 23 at 0:56


















                     

                    draft saved


                    draft discarded



















































                     


                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f483292%2fhow-to-write-regexp-literal-in-match-expression%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

                    flock() on closed filehandle LOCK_FILE at /usr/bin/apt-mirror

                    Mangá

                    Eduardo VII do Reino Unido