Loop's regex conditional doesn't work using extended test

Viewed 39

I have a loop that evaluates based on a regex conditional:

until   read -p "Enter oprator: " operator
        [[ $operator =~ ^[+-*\/]$ ]] #doesn't work
do...

The loop will run until the user enters an arithmetic operator (+, -, * or /). When I enter any of those four, the loop still runs.

I've tried variations of this (i.e. place regex in variable, using quotes, grep) but nothing seems to work.

2 Answers
^[+-*\/]$ ]]$

Here problem is placement of an unescaped - in the middle of the bracket expression which acts as a range between + and *.

You may use this regex (no need to escape / in BASH regex):

[[ $operator =~ ^[-+*/]$ ]]

Or even better without regex use glob match:

[[ $operator == [-+*/] ]]

When including the dash or minus sign - in a character class of a Regex, it must be first or last position, or it will be handled like a range marker. Also the slash / does not need escaping with a backslash:

#!/usr/bin/env bash

until 
  read -r -n1 -p "Enter oprator: " operator
  printf \\n
  [[ "$operator" =~ [+*/-] ]] #doesn't work
do
  printf 'Symbol %q is not an operator!\n' "$operator" >&2
done

POSIX shell grammar implementation:

#!/usr/bin/env sh

until
  printf 'Enter oprator: '
  read -r operator
  printf \\n
  [ -n "$operator" ] && [ -z "${operator%%[-+*/]}" ]
do
  printf 'Symbol %s is not an operator!\n' "$operator" >&2
done
Related