Search code examples
regexexpr

How to use `expr` when there's an optional substring in the regex?


I want to find the go[^ ]+ inside these two strings using expr. The output should be 1.17.6 and 1.18-becaeea119.

go version go1.17.6 linux/amd64
go version devel go1.18-becaeea119 Tue Dec 14 17:43:51 2021 +0000 linux/amd64

However, the devel part is optional and I can't figure out a way to properly ignore it with expr.

expr "$(go version)" : ".*go version go\([^ ]*\) .*"
expr "$(go version)" : ".*go version devel go\([^ ]*\) .*"

Using normal regexes, I would just (?: devel)? it, but expr doesn't support ? for some reason.

Is there any way to achieve this using expr in one command?


Solution

  • Use

    .*go version.* go\([^[:space:]]*\) .*
    

    EXPLANATION

    --------------------------------------------------------------------------------
      .*                       any character (0 or more times)
    --------------------------------------------------------------------------------
      go version               'go version'
    --------------------------------------------------------------------------------
      .*                       any character (0 or more times)
    --------------------------------------------------------------------------------
       go                      ' go'
    --------------------------------------------------------------------------------
      \(                       group and capture to \1:
    --------------------------------------------------------------------------------
        [^[:space:]]*            any character except: whitespace
                                 characters (0 or more times)
    --------------------------------------------------------------------------------
      \)                       end of \1
    --------------------------------------------------------------------------------
                               ' '
    --------------------------------------------------------------------------------
      .*                       any character (0 or more times)