I have a complex string of this form:inp=key1 =   what' ever the value key2 = the value Nb.2   key3= \last value\I need to get the first key associated with its first value. I want to use bash regex to extract the key, the value, and what remains from the string:rkeyval=[[:space:]]*([_[:alnum:]]*?)[[:space:]]*=[[:space:]]*((.*?)[[:space:]]+([_[:alnum:]]+?[[:space:]]*=[[:space:]]*.*))if [[ $inp =~ $rkeyval ]]; then  key=${BASH_REMATCH[1]}  val=${BASH_REMATCH[3]}  left=${BASH_REMATCH[4]}  for i in $(seq 0 $(( ${#BASH_REMATCH[*]}-1 ))); do      echo -e $i: \${BASH_REMATCH[$i]}\;   done; else  echo no matchfiThis does not work. On my Mac with Bash 4.4, there is no match:no matchOn my Red Hat Linux, I get the following output:0: key1 =   what' ever the value key2 = the value Nb.2   key3= last value1: key12: what' ever the value key2 = the value Nb.2   key3= last value3: what' ever the value key2 = the value Nb.2  4: key3= last valueI expect the following output:0: key1 =   what' ever the value key2 = the value Nb.2   key3= last value1: key12: what' ever the value key2 = the value Nb.2   key3= last value3: what' ever the value4: key3= last valueIn other words, the key would be the second matching group, and the value the third.This expression works on an online PHP regexp tester.I want this to work in any Unix machine having an updated version of Bash.I don't know why this does not work, and why the result differ from one platform to another, even though my regex respects the Posix convention (or does it?). What am I doing wrong here?
bash regex extract key = value
bash;regular expression;posix
An asterisk is already an optional count (as it could be zero characters).  There is no need to add an ? to it.So, Will it be ok if each parenthesis will capture a key or a value?:s='[[:space:]]*'        # spacesn='[_[:alnum:]]+'       # a valid name (limited by spaces)e=${s}=${s}           # an equal sign (=).rkeyval=${s}(${n})${e}([^=]*) (${n})${e}([^=]*) (${n})${e}(.*)#            1^^^^^    2^^^^^^ 3^^^^^    4^^^^^^ 5^^^^^    6^^^echo $rkeyvalThat will capture like this:if [[ $inp =~ $rkeyval ]]; then    i=0    while ((i<${#BASH_REMATCH[@]})); do        printf '%s: %s\n' $((i)) ${BASH_REMATCH[i++]};    doneelse    echo no matchfiPrinting:0: key1 =   what' ever the value key2 = the value Nb.2   key3= last value1: key12: what' ever the value3: key24: the value Nb.2  5: key36: last valueAnd the values you want (if I understand your code correctly) could be approximated by (edit to get a perfect match):key=${BASH_REMATCH[1]}val=${BASH_REMATCH[@]:2:3}left=${BASH_REMATCH[@]:5:2}