【问题标题】:Bash RegEx to check floating point numbers from user inputBash RegEx 从用户输入中检查浮点数
【发布时间】:2012-11-27 06:21:39
【问题描述】:

我对 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]*$

等等等等

另外,我还绑定了其他执行检查的方法:

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

我还需要它来处理浮点数。

有人可以让我知道我该怎么做吗?

【问题讨论】:

  • 我希望您不需要12345e42 形式的数字。

标签: regex bash expression bash4


【解决方案1】:

此正则表达式 ^[-+]?[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]*

解释:

^       # 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.,不确定这是否适合您。

编辑:不要引用regex

testNo=30.00

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

>>> Match

【讨论】:

  • 这将不匹配负数。 :-(
  • 忘记那些事了:|
  • 好。现在我希望OP不需要1.2345e42
  • 感谢您的帮助,我写了这个:` if [[ $testNo =~ ^[+-]?[0-9]+\.?[0-9]*$' ] ] `但它似乎不喜欢浮点数,它说它们不是数字,我所做的是否正确?干杯。
【解决方案2】:

要使用该类型的功能,您需要条件的[[ ... ]] 版本。 [ 是“旧的”test 命令,根本不处理正则表达式。

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

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

关于正则表达式的解释:

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

这两个使正则表达式匹配传递的整个字符串,不允许部分匹配。

[+-]

匹配+-

[+-]?

使该部分成为可选部分,因此上述内容完全匹配 +- 或根本不匹配。

如果part1part2 匹配,则(part1|part2) 将匹配。

第一部分是:

[0-9]+\.?

匹配一个或多个 (+) 数字(但不是零数字/空集)和可选的 .。这处理123534. 形式的数字。但不仅仅是.

第二部分是:

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

这匹配零个或多个 (*) 数字,后跟 .,后跟一个或多个数字。这匹配所有其他浮点数,例如 1.3.543(没有指数符号),但仍然仅排除 .

【讨论】:

  • testNo=hello2you ---> That is a number! :-(.
  • 是的,感谢您的关注 :) 现在应该可以处理合理的浮动了。
  • 负浮点数除外,42..42 形式的浮点数除外
  • 艰难的人群!我不确定我是否喜欢 42. 被接受(如果您仍想排除 .,这会使正则表达式有点毛茸茸 - 可能是更好的选择),但 .42 是完全合理的。还是编辑了。
【解决方案3】:
#!/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

【讨论】:

    【解决方案4】:

    我在开头添加了一个可选的点。

           user@debian:~$ testNo=.01
           user@debian:~$ if [[ $testNo =~ ^[+-]?[.]?[0-9]+\.?[0-9]*$ ]]; 
                        > then         
                        > echo Match; 
                        > fi
             Match
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多