这在语法上是错误的:
#!/usr/bin/env bash
dimension="4x5"
if [[ "$dimension" !=~ '[0-9]x[0-9]' ]]; then
echo 'wtf meng, the dimension needs an "x" in it.'
return 1;
fi
上面的语法很糟糕......所以我的问题是 - 有没有办法做到!=~
...我猜是吗!~
?如果这是真的,那么否定规则就到此为止了lulz。好吧我测试了!~
一下也没用..
答案1
关键字没有!=~
or!~
运算符[[
。相反,对比较结果取反:
[[ ! "string" =~ regex ]]
关于引用regex
论点,手册指出:
模式的任何部分都可以被引用,以强制引用的部分作为字符串进行匹配。
regex
因此,不应引用 的正则表达式部分– 除非compat31
设置了 shell 选项:
shopt
...compat31
如果设置,bash 将其行为更改为版本 3.1 中
[[
条件命令=~
运算符的引用参数的行为
对于给定的示例,请尝试:
if [[ ! "$dimension" =~ ^[0123456789]+x[0123456789]+$ ]]; then
printf '%s %s\n' "'$dimension'" 'is not a valid dimension.'
fi
regex
应锚定^...$
,否则foo1x1fubar
将被视为有效维度。
还要记住不要使用像0-9
输入验证这样的范围,特别是如果它是为了在安全敏感的上下文中进行清理,就像在许多语言环境中一样,这些范围包含比历史上更多的字符(或者可能整理由多个字符组成的元素)(并且在 C/POSIX 语言环境中仍然如此)。
因为=~
,在这里bash
没有globasciiranges
帮助。在 Ubuntu 19.10 和en_GB.UTF-8
语言环境中,我发现除了 0123456789 之外,还可以匹配 1040 个不同的字符,无论是否bash
带有。至少在我的例子中,它们都与十进制数字 0 到 8 存在某种关系,但这通常不能保证。[0-9]
globasciiranges
另一方面,[[:digit:]]
和[0123456789]
只匹配这 10 个 且 应该在任何 POSIX 兼容系统上。
您还可以使用标准sh
语法和通配符模式来完成此操作,例如:
valid_geometry() case $1 in
(*[!x0123456789]* | *x | x* | *x*x*) false;;
(*x*) true;;
(*) false;;
esac
if ! valid_geometry "$dimension"; then
...
fi
或者使用 ksh globs (也受 和 的支持,甚至bash -O extglob
没有bash
):[[
extglob
if [[ $dimension != +([0123456789])x+([0123456789]) ]]; then
...
fi
答案2
好吧,这似乎有效:
if [[ ! "$dimension" =~ [0-9]+x[0-9]+ ]]; then
echo 'wtf meng, the dimension needs an "x" in it.'
exit 1;
fi
但我想知道为什么用单引号括起来不起作用:
if [[ ! "$dimension" =~ '[0-9]+x[0-9]+' ]]; then
echo 'wtf meng, the dimension needs an "x" in it.'
exit 1;
fi
这是我的解决方案:
dimension="3x5"
regex='[0-9]+x[0-9]+'
if [[ ! "$dimension" =~ $regex ]]; then
echo 'wtf meng, the dimension needs an "x" in it.'
exit 1;
fi
现在您可以使用单引号来引用正则表达式,但在 [[ ]] 内引用 $regex 时必须避免使用双引号。不过我仍然很好奇是否有[0-9]+
..的简写