Regular expression to match floating point numbers in shell script

5,340

Solution 1

First of all, your code has a syntax error and should complain about:

bash: [: =~: binary operator expected

Assuming you are running bash, but based on your code, you probably are. So, in bash, the =~ only works inside [[ ]], not [ ]. You also shouldn't quote your regular expression. You are looking for something like this:

$ for f in $float_numbers; do 
    [[ $f =~ [0-9]*\.?[0-9]* ]] && echo $f
  done
1.2
10.5
4.0

However, as Glenn very correctly pointed out, your regex is wrong in the first place.

Solution 2

terdon has corrected your syntax, but your regular expression is wrong:

[0-9]*\.?[0-9]*

All quantifiers there (*, ?) mean all parts of the expression are optional. That means your regex will match every string, including strings that are empty and strings that have no digits.

To match a float number, you need to match at least one digit.

([0-9]+\.?[0-9]*)|([0-9]*\.[0-9]+)

That matches some digits with an optional decimal point and optional digits (example: 3.14 or 42), or some optional digits but a required decimal point and required digits (example: .1234 or 3.14).

It is not anchored, so the string "PI starts with 3.14 and continues" will match.

Testing:

for n in "" "no digits" 42 3.14 "this is .1234 go"; do 
    if [[ $n =~ ([0-9]+\.?[0-9]*)|([0-9]*\.[0-9]+) ]]; then
        echo "yes -- $n -- ${BASH_REMATCH[0]}"
    fi
done
yes -- 42 -- 42
yes -- 3.14 -- 3.14
yes -- this is .1234 go -- .1234
Share:
5,340

Related videos on Youtube

Gaurav KS
Author by

Gaurav KS

Updated on September 18, 2022

Comments

  • Gaurav KS
    Gaurav KS almost 2 years

    I'm using a regular expression to match floating point numbers:

    for f in $float_numbers ; do
        if [ $f =~ "[0-9]*\.?[0-9]*" ] ; then
            echo "****f is $f ****"
        fi
    done
    

    where $float_numbers contains floating point numbers like 1.2, 10.5, 4.0, etc.

    But nothing matches.

    • terdon
      terdon over 7 years
      When asking a question, you should also include the error messages you are getting.
  • terdon
    terdon over 7 years
    Why would you use \\d* instead of \d? Why are you using a negative lookahead there? You are matching "1 or more digits" (\d+) and "not followed by =,-, . or more digits. I dont' understand why that helps in any way.
  • Wissam Roujoulah
    Wissam Roujoulah over 7 years
    @terdon i totally agree with you i didn't find any reason to (?![-+0-9\\.])