This answer does not refer to the already explained case
problem but to the matching problem.
First we need a definition what the valid strings may look like. The easiest definition would, of course, allow only one structure like
- start with one or more digits (leading zeroes allowed)
- decimal dot
- two trailing digits (if necessary
00
)
- Dollar sign (no leading space)
As a regular expression (for e.g. grep
, see man 7 regex
) this would be written as:
^[0-9]+\.[0-9][0-9]\$$
^
marks the beginning of the string i.e. there can be nothing before the [0-9]+
- The dot is escaped
\.
in order to be treated as literal dot
- The Dollar sign is escaped
\$
in order to be treated as literal
- the trailing
$
marks the end of the string i.e. there can be nothing after the literal $
Testing:
> echo '0123.45$' | grep -E '^[0-9]+\.[0-9][0-9]\$$'
0123.45$
If the definition is changed so that both the dot with the trailing digits and the Dollar sign are optional then the regex would change to
^[0-9]+(\.[0-9][0-9])?\$?$
Testing:
> echo '0123$' | grep -E '^[0-9]+\.[0-9][0-9]\$$'
# no match
> echo '0123$' | grep -E '^[0-9]+(\.[0-9][0-9])?\$?$'
0123$
> echo '0123.45$' | grep -E '^[0-9]+(\.[0-9][0-9])?\$?$'
0123.45$
The shell can work with regular expressions directly but not within case
patterns. You need the [[ ]]
structure. But as you want to know only whether a string matches or not anyway there is no reason to use case
:
if [[ "$price" =~ ^[0-9]+(\.[0-9][0-9])?\$?$ ]]; then
:
else
:
fi
If you really need case
then you can set the option extglob
with the shell bulitin shopt
and rewrite the regex to a "shell regex":
shopt -s extglob
^[0-9]+(\.[0-9][0-9])?\$?$
becomes then
+([0-9])?(.[0-9][0-9])?($)
leading $
If you want $0123.45
instead of 0123.45$
then you obviusly have to put the check for $
at the start:
grep
/ [[ ]]
: ^\$?[0-9]+(\.[0-9][0-9])?$
- shell pattern matching:
?($)+([0-9])?(.[0-9][0-9])
easier check
If you don't care about the order but just about the right chars then you can use much easier expressions:
grep
/ [[ ]]
: ^[0-9.$]+$
- shell pattern matching:
+([0-9.$])
example
#! /bin/bash
shopt -s extglob
for value in 1234 1234EUR; do
case "$value" in
+([0-9]))
echo "value OK: '${value}'"
;;
*)
echo "value not OK: '${value}'"
;;
esac
done
[0-9] | "." | "$"
matches what you want? I would rather expect something like (in bash withextglob
enabled):?($)+([0-9])?(.+([0-9]))
(matching$123.45