4

This question is not a duplicate of any other questions around here as I need a regex in bash with the =~ matching.

Assuming I have a string like

string="ananas1kiwi2apple1banana2tree"

The regEx I tried was

[[ $string =~ .*2([[:alnum:]]{1,}) ]] && subString=${BASH_REMATCH[1]}

which was supposed to match the occurrence of 2 and capture everything beyond that, which is returning me only tree (string after the 2nd match). My expected output is apple1banana2tree

I know am missing a simple construct but not exactly sure which. Am looking only for a pure bash regEx based solution. Also not any string manipulation which I know can be done by "{string#*2}"

  • Definitely a duplicate... plenty of questions out there about how to match before or after - this is a regex question, not a shell one. – don_crissti Nov 9 '16 at 12:56
3

Just match 2 and then capture everything beyond by .*:

[[ $string =~ 2(.*) ]] && echo "${BASH_REMATCH[1]}"

Example:

$ string="ananas1kiwi2apple1banana2tree"

$ [[ $string =~ 2(.*) ]] && echo "${BASH_REMATCH[1]}"
apple1banana2tree

What's wrong with your one:

  • .* is greedy, it is matching upto last 2 when you use .*2, to have non-greediness (as .*? is not available in ERE) use [^2]*2

  • Also {1,} is just +

So do:

[[ $string =~ [^2]*2([[:alnum:]]+) ]]

In any case, no need to match from the start, just do:

[[ $string =~ 2([[:alnum:]]+) ]]
| improve this answer | |
  • Also I don't need the greedy .* before 2? Just checked that .* before 2 isn't working. Any reason why? – Inian Nov 9 '16 at 12:55
  • @Inian Check my edits. – heemayl Nov 9 '16 at 13:01
  • That's just great! – Inian Nov 9 '16 at 13:02
  • 1
    Note that it would have to be [[ $string =~ '2(.*)' ]] in bash-3.1. Or re='2(.*)'; [[ $string =~ $re ]] to be compatible with both 3.1 and 3.2+ (and zsh and ksh93). Note that bash-3.2+ and ksh93 have problems with things like [[ x =~ [)}]+ ]] which bash31 didn't have. You can use shtop -s compat31 to get back to the older behaviour. – Stéphane Chazelas Nov 9 '16 at 13:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.