0

我有一个 Bash 函数f,它将字符串值s作为其参数之一。

s如果之间不是整数,我需要中止执行[1000-9999]

我最初以为我会尝试将字符串转换为 int 并对结果执行算术范围检查,在错误时中止,但所有其他参数都使用 RegEx 检查,所以我不妨保持一致。我必须,事实上。

重击版本:4+

我想不出比这更好看的模式:

[[ "$s" =~ [[:\<:]][[:digit:]]{4}[[:\>:]] ]]

你能帮我提高上面的模式检查结构的可读性吗?

我特别不喜欢上面的模式是:

  • 必须用反斜杠将单词边界字符转义<[[:\<:]]
  • 它的绝对长度,以及方括号的疯狂数量

我的一个想法是使用全线边界检查,尽管那是一种黑客行为?(即使用 ^...$ 而不是 \b...\b)


可选:: 在 Bash 中是否存在相当完善的参数验证模式?

4

3 回答 3

2

另外,我会尝试:

[[ $s =~ ^[1-9][0-9]{3}$ ]]

否则0999会通过。但另一方面可能+1234是有效的输入,可能也是如此1234.0,所以如果你需要完整,你可能需要扩展你的正则表达式,或者毕竟执行值检查..

于 2013-03-10T10:59:51.023 回答
2

bash可以进行整数比较:

shopt -s extglob # Needed for the extended pattern +(...)
f () {
    if [[ $1 == +([[:digit:]]) ]] &&
       (( $1 >= 1000 && $1 < 10000 )); then
    ...
    fi
}
于 2013-03-10T13:46:40.307 回答
1

http://mywiki.wooledge.org/BashFAQ/054

你可以只使用模式匹配来做到这一点,但我会拆分它。我会说这样的事情接近“通常”的方法:

f() {
    if [[
        $1 == +([[:digit:]]) &&
        "$1 >= 1000 && $1 < 10000" -ne 0
        ]]
    then
        ...
    fi
}

在 Bash/ksh 测试表达式复合命令中,数值比较运算符的参数被计算为算术表达式。双引号允许表达式中包含空格,否则解析器无法区分某些算术运算符和测试表达式运算符。检验左边的表达式是否0基本等价于(()). 这与@chepner 的答案相同,除了只使用一个命令。我希望这会表现得稍微好一些,而且我已经习惯了语法,所以对我来说很清楚。有些人更喜欢另一种方式。您应该只在与其他一些测试结合使用时使用[[算术运算符。((

在将任何不可预测的输入用作算术表达式之前,您必须先进行验证。然后你可以检查它是否在一定范围内。还有其他方法可以做到这一点,但这是我个人的做法。这很清楚,适用于这个问题的所有排列。

我还应该补充一点,如果您的输入可能包含八进制或十六进制文字,则需要进一步处理。在这种情况下,通常运行输入printf %d效果很好。

于 2013-03-10T11:38:03.367 回答