2012-12-09 10 views
6

Jestem stosunkowo nowy w programowaniu bash i obecnie tworzę prosty kalkulator.Bash RegEx, aby sprawdzić liczby zmiennoprzecinkowe od użytkownika input

Należy użyć liczb zmiennoprzecinkowych i sprawdzić, czy tak się dzieje.

Mam funkcji 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 
} 

gdzie ja dostać użytkownikowi wprowadzenie numeru tak:

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

ten nie działa, otrzymuję ten błąd:

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

linia 39 to:

if [ $testNo =~ $regExp ] 

próbowałem wiele wyrażeń regularnych takich jak:

^*[0-9]*$ 

i

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

itp itd

również, mam przywiązane innych sposobów wykonywania czek:

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

i

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

Potrzebuję tego również do pracy z liczbami zmiennoprzecinkowymi.

Czy ktoś mógłby mi powiedzieć, jak to rozumiem?

+0

Mam nadzieję, że nie trzeba liczb postaci '12345e42'. –

Odpowiedz

7

Ten regex ^[-+]?[0-9]+\.?[0-9]*$ będzie pasował tylko cyfry z opcjonalną .:

$ 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 

myślę kiedy próbował ^*[0-9] chciałeś ^[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 

Uwaga: to pasuje numery a następnie ., takich jak 30., nie t pewnie, czy jest to dla ciebie do przyjęcia.

Edit: Nie cytujemy regex

testNo=30.00 

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

>>> Match 
+0

To nie będzie pasowało do liczb ujemnych. ':-(' –

+0

Zapomniałem o tych rzeczach: | –

+0

Dobrze, teraz mam nadzieję, że OP nie potrzebuje '1.2345e42'. –

2

Do korzystania z tego typu funkcji wymagana jest wersja warunkowa [[ ... ]]. [ jest "starą" komendą test i nie obsługuje w ogóle wyrażeń regularnych.

#! /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! 

Zobacz What is the difference between test, [ and [[ ?.

Wyjaśnienie na regex:

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

Te dwa uczynić regex dopasować cały ciąg minęło, częściowe wyniki nie są dozwolone.

[+-] 

mecze albo + lub -.

[+-]? 

sprawia, że ​​część opcjonalna, więc powyższych meczów dokładnie +, - albo w ogóle nic.

Następnie jest alternacja (part1|part2), która będzie pasować, jeśli pasuje part1 lub part2.

Część z nich jest:

[0-9]+\.? 

który pasuje do jednego lub więcej (+) cyfry (ale nie zerowe cyfry/zbiór pusty) i opcjonalny .. Obsługuje numery w postaci 123 i 534.. Ale nie tylko ..

Część druga jest:

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

Dopasowuje zero lub więcej (*) cyfr, a następnie przez ., a następnie przez jeden lub więcej cyfr. Dopasowuje wszystkie pozostałe zmienne, takie jak 1.3 lub .543 (bez notacji wykładniczej), ale nadal wyklucza tylko ..

+0

'testNo = hello2you' --->' To jest liczba! '' :-('. –

+0

Haha! Dobrze, że oglądam' ;-) ' –

+0

Tak, dziękuję za obserwowanie :) Powinien obsługiwać rozsądne pływaki teraz. – Mat

1
#!/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 
Powiązane problemy