Bash中匹配负整数/负浮点数及在if语句实现数值判断的方法
问题解答
1. 正则匹配有效性判断
你给出的正则[[ "$1" =~ [^-[0-9]*([.]*[0-9]*)$] ]]无法匹配目标负整数/负浮点数,存在以下核心错误:
- 行首匹配符
^写在了[]字符集内部,含义变为「匹配非-、非数字的字符」,完全违背了「以负号开头」的校验要求 [.]*允许出现多个小数点,会匹配到-12.34.56这类非法浮点数- 允许
-.这类没有任何有效数字的无效值通过校验
如果你需要用正则覆盖你列出的所有合法负数场景,修正后的写法如下:
[[ "$1" =~ ^-([0-9]+\.?[0-9]*|\.[0-9]+)$ ]]
该正则的校验规则:
- 必须以
-开头 - 支持两种合法格式:
- 数字开头,可选带小数点和后续小数位(覆盖
-67、-0.0000000000667、-67.0000000000667) - 小数点开头,后必须跟数字(覆盖
-.0000000000667)
- 数字开头,可选带小数点和后续小数位(覆盖
- 最多允许1个小数点,不会匹配多小数点、无有效数字的非法值
2. bc校验函数集成到if语句的方案
bash原生的(( ))算术扩展仅支持整数比较,传入浮点数会直接报错,你定义的ngnum函数返回值规则为:输入小于0时返回1,输入大于等于0时返回0,直接基于返回值做判断即可,修改后的完整代码如下:
# 负数判断函数 ngnum () { echo "$1 < 0" | bc -l } # 可选:先做参数合法性校验,避免非法值传入bc导致报错 if ! [[ "$1" =~ ^-?([0-9]+\.?[0-9]*|\.[0-9]+)$ ]]; then echo "输入参数不是合法数值" >&2 exit 1 fi # 基于bc函数的判断逻辑 if [[ $(ngnum "$1") -eq 0 ]]; then # 非负数取整逻辑 inear=$( echo "($1 + 0.5) / 1" | bc ) else # 负数取整逻辑 inear=$( echo "($1 - 0.5) / 1" | bc ) fi
该方案的优势是和你后续的bc计算逻辑精度完全对齐,不会出现正则校验合法但bc不识别、或者浮点数精度判断偏差的问题。
内容的提问来源于stack exchange,提问作者Han
相关产品推荐
相关产品推荐

