您好我尝试验证用户输入不为空并且是数字或带小数
re='^[0-9]+$'
while [ "$num" == "" ] && [[ "$num" ~= $re ]]
do
echo "Please enter the price : "
read num
done
我能够在第一个条件下顺利运行。当我添加第二个条件时,我的程序无法运行。
---- EDIT ----------
好的,我尝试更改并运行程序。但是当我输入一个数字时,它仍然会提示输入。
re='^[0-9]+$'
while [ "$num" == "" ] && [ "$num" != $re ]
do
echo "Please enter the price : "
read num
done
答案 0 :(得分:2)
regualar表达式可以与运算符=~
一起使用,而非~=
,就像您使用它一样。
可以使用另外的二元运算符=〜 在dence as = =和!=之前。当它被使用时,在右边的字符串
运算符被视为扩展正则表达式并匹配 因此(如正则表达式(3))。如果是字符串,则返回值为0 匹配模式,否则为1。如果是正则表达式 在语法上不正确,条件表达式的返回值是 2.如果启用了shell选项nocasematch,则执行匹配 不考虑字母字符的情况。任何一部分 可以引用模式以强制引用的部分匹配为a 串。必须处理正则表达式中的括号表达式 仔细,因为正常的引用字符之间失去了意义 括号。如果模式存储在shell变量中,则引用 变量扩展强制整个模式匹配为字符串。 子字符串与常规中带括号的子表达式匹配 表达式保存在数组变量BASH_REMATCH中。元素 索引为0的BASH_REMATCH是与之匹配的字符串部分 整个正则表达式。索引为n的BASH_REMATCH元素为 匹配第n个带括号的子表达式的字符串部分。
考虑这些例子(0真/匹配,1假/不匹配)
re=^[0-9]+; [[ "1" =~ ${re} ]]; echo $? # 0
re=^[0-9]+; [[ "a" =~ ${re} ]]; echo $? # 1
re=^[0-9]+; [[ "a1" =~ ${re} ]]; echo $? # 1
re=^[0-9]+; [[ "1a" =~ ${re} ]]; echo $? # 0 because it starts with a number
使用这个来检查数字
re=^[0-9]+$; [[ "1a" =~ ${re} ]]; echo $? # 1 because checked up to the end
re=^[0-9]+$; [[ "11" =~ ${re} ]]; echo $? # 0 because all nums
更新:如果您只想检查用户是否输入了一个数字,请将上述经验教训与您的需求结合起来。我认为你的条件不合适。也许这个片段完全解决了你的问题。
#!/bin/bash
re=^[0-9]+$
while ! [[ "${num}" =~ ${re} ]]; do
echo "enter num:"
read num
done
如果${num}
不是!
),则此代码段仅请求输入。在第一次运行期间${num}
未设置,因此它不适合至少一个数字,${num}
然后计算为空字符串。之后它只包含输入的输入。
答案 1 :(得分:1)
你的错误很简单;变量不能同时为空和数字。也许你的意思是||
“或”而不是&&
“和”。
您也可以使用glob模式执行此操作。
while true; do
read -r -p "Enter a price: " num
case $num in
"" | *[!.0-9]* | *.*.*) echo invalid ;;
*) break;;
esac
答案 2 :(得分:0)
首先,OP的问题演示了经典的逻辑陷阱:
while [ "$num" == "" ] && [ "$num" != $re ]
这里的问题是&&
,这在很大程度上意味着当左表达式为false
时,整个表达式为false
。即,当有人键入非空响应时,它中断了循环,并且从不使用正则表达式测试。要解决逻辑问题,应该考虑将&&
更改为||
,即
while [ "$num" == "" ] || [ "$num" != $re ]
第二个问题是,我们正在测试与正则表达式,模式的否定匹配。因此,这分为两个部分,其中一个部分我们需要使用[[ "$num" =~ $re ]]
进行正则表达式测试。然后,我们需要查找否定匹配项,即附加一个!
,其结果是:
while [ "$num" == "" ] || ! [[ "$num" =~ $re ]
到目前为止,许多人发现实际上不需要测试空字符串。正则表达式本身已经覆盖了边缘条件,因此,我们优化了冗余测试。答案现在变为:
while ! [[ "$num" =~ $re ]
除了上述观察之外,这是我关于正则表达式的注释(一些观察已从其他答案中整理得出):
[[ "$str" =~ regex ]]
语法测试正则表达式$? == 0
匹配(0 ==没有错误)$? == 1
不匹配(1 ==错误)[0-9]
而不是"[0-9]"
要实施数字验证,似乎可以使用以下模式:
str=""
while ! [[ "${str?}" =~ ^[0-9]+$ ]]
do
read -p "enter a number: " str
done
您可以将正则表达式过滤器与正则算术过滤器混合使用,以获得一些非常不错的验证结果:
str=""
while ! [[ "${str?}" =~ ^[0-9]+$ ]] \
|| (( str < 1 || str > 15 ))
do
read -p "enter a number between 1 and 15: " str
done
我使用${str?}
语法(而不是$str
)进行变量扩展,因为它演示了捕获错别字的好习惯。