Регулярное выражение Bash для проверки чисел с плавающей запятой из пользовательского ввода

Я относительно новичок в программировании bash, и в настоящее время я создаю простой калькулятор.

он должен использовать числа с плавающей запятой и проверить, что они таковы.

у меня есть функция checkNumbers:

function checkNumber {

    regExp=[0-9]

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

где я получаю пользователя для ввода такого числа:

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

это не работает, я получаю эту ошибку:

./calculator.sh: строка 39: [:=~: ожидается двоичный оператор

строка 39 есть:

if [ $testNo =~ $regExp ] 

Я пробовал много регулярных выражений, как:

^*[0-9]*$

и

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

etc etc.

кроме того, я связал другие способы выполнения проверки:

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

и

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

мне также нужно это для работы с числами с плавающей запятой.

может кто-нибудь, пожалуйста, дайте мне знать, как я это сделаю?

3 ответов


это регулярное выражение ^[-+]?[0-9]+\.?[0-9]*$ будет соответствовать только цифры с дополнительным .:

$ 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

Я думаю, когда ты пробовал ^*[0-9] хотел ^[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

Примечание: это соответствует номерам, за которыми следует . как 30., не уверен, что это приемлемо для вас.

Edit: Не цитируйте regex

testNo=30.00

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

>>> Match

чтобы использовать этот тип функции, вам нужно [[ ... ]] версия условным. [ - это "старые" и не обрабатывает регулярные выражения вообще.

#! /bin/bash
function checkNumber {
    regExp='^[+-]?([0-9]+\.?|[0-9]*\.[0-9]+)$'
    if [[ $testNo =~ $regExp ]]
    then
        echo "That is a number!"
        let check=1
    else
        echo "Damn! Not A Number!"
    fi
}
testNo=1
checkNumber
testNo=-1.2
checkNumber
testNo=+.2
checkNumber
testNo=+0.
checkNumber
testNo=a
checkNumber
testNo=hello2you
checkNumber

$ ./t.sh
That is a number!
That is a number!
That is a number!
That is a number!
Damn! Not A Number!
Damn! Not A Number!

посмотреть в чем разница между test, [ и [[ ?.

объяснение по регулярному выражению:

^ Anchor at start of string
$ Anchor at end of string

эти два делают регулярное выражение совпадающим со всей переданной строкой, частичные совпадения не допускаются.

[+-]

соответствует + или -.

[+-]?

делает эту часть необязательной, поэтому вышеуказанное соответствует точно +, - или вообще ничего.

тогда есть чередование (part1|part2) что будет соответствовать, если part1 или part2 матчи.

Часть первая:

[0-9]+\.?

, который соответствует одному или более (+) цифры (но не нулевые цифры / пустой набор) и необязательный .. Это обрабатывает номера формы 123 и 534.. Но не только ..

Часть вторая:

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

это соответствует нулю или более (*) цифры, за которыми следует ., за которым следует одна или более цифр. Это соответствует всем другим поплавкам, как 1.3 или .543 (без обозначения экспоненты), но все равно исключает только ..


#!/bin/bash
#script to validate 

while [ true ]; do
clear
echo "Introduce the numeric value: "
read -r var
if [[ $var =~ ^[+-]?([0-9]+)$ ]]
   then
      echo "You introduced an integer value (without decimals)"
      read
   else
      if [[ $var =~ ^[+-]?([0-9]+\.)$ ]]
         then
            echo "Incomplete floating value (no values provided at the right of the point)"
            read
         else
            if [[ $var =~ ^[+-]?(\.[0-9]+)$ ]]
               then
                  echo "Incomplete floating value (no values provided at the left of the point)"
                  read
               else
                  if [[ $var =~ ^[+-]?([0-9]+\.[0-9]+)$ ]]
                     then
                        echo "You introduced a correct floating value"
                        read
                     else
                        echo "You introduced something other than a valid numeric value"
                        read
                  fi
            fi
      fi
fi
done