如何使用测试否定正则表达式

如何使用测试否定正则表达式

这在语法上是错误的:

#!/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]+..的简写

相关内容