Bash RegEx to check floating point numbers from user input

Sam_Web picture Sam_Web · Dec 9, 2012 · Viewed 11.5k times · Source

I'm relatively new to bash programming and i am currently creating a simple calculator.

It needs to use floating point numbers and check they are so.

I have a checkNumbers function:

function checkNumber {

    regExp=[0-9]

    if [ $testNo =~ $regExp ]
    then
        echo "That is a number!"
        let check=1
    else
        echo "Damn! Not A Number!"
    fi
}

where i get the user to input a number like this:

while [ $check -eq 0]
do
    echo "Please enter a number
    read testNo
    echo ""
    checkNumber
done

This does not work, i get this error:

./calculator.sh: line 39: [: =~: binary operator expected

line 39 is:

if [ $testNo =~ $regExp ] 

I have tried lots of Regular Expressions like:

^*[0-9]*$

and

^*[0-9]\.[0.9]*$

etc etc.

also, i have tied other ways of performing the check:

case $testNo
in
    ^*[0-9]*$) echo "That is a number!";;
    *) echo "Error! Not a number!";;
esac

and

if [ $testNo = ^*[0-9]*$ ]
then
    echo "etc etc"
else
    echo "oops"
fi

I also need this to work with floating point numbers.

could someone please let me know how i go about this?

Answer

Chris Seymour picture Chris Seymour · Dec 9, 2012

This regex ^[-+]?[0-9]+\.?[0-9]*$ will match only digits with an optional .:

$ echo 30 | grep -Eq '^[-+]?[0-9]+\.?[0-9]*$' && echo Match
Match

$ echo 30.10 | grep -Eq '^[-+]?[0-9]+\.?[0-9]*$' && echo Match
Match

$ echo 30. | grep -Eq '^[-+]?[0-9]+\.?[0-9]*$' && echo Match
Match

$ echo +30 | grep -Eq '^[-+]?[0-9]+\.?[0-9]*$' && echo Match
Match

$ echo -30 | grep -Eq '^[-+]?[0-9]+\.?[0-9]*$' && echo Match
Match

I think when you tried ^*[0-9] you wanted ^[0-9]*

Rexeplanation:

^       # Match start of string
[-+]?   # Match a leading + or - (optional)
[0-9]+  # Match one or more digit
\.?     # Match a literal . (optional, escaped)
[0-9]*  # Match zero or more digits
$       # Match the end of the string

Note: this matches numbers followed by a . like 30., not sure if this is acceptable for you.

Edit: Don't quote the regex

testNo=30.00

if [[ $testNo =~ ^[+-]?[0-9]+\.?[0-9]*$ ]]; then 
    echo Match
fi

>>> Match