我做错了什么?
尝试匹配任何包含空格、空格、空格或数字的字符串。特殊字符也很好,但我认为这需要转义某些字符。
TEST="THIS is a TEST title with some numbers 12345 and special char *&^%$#"
if [[ "$TEST" =~ [a-zA-Z0-9\ ] ]]; then BLAH; fi
这显然只测试了上、下、数字和空格。但不管用。
- 更新 *
我想我应该说得更具体一点。下面是实际的真实的代码行:
if [[ "$TITLE" =~ [a-zA-Z0-9 $%^\&*#] ]]; then RETURN="FAIL" && ERROR="ERROR: Title can only contain upper and lowercase letters, numbers, and spaces!"; fi
这就是错误:
./anm.sh: line 265: syntax error in conditional expression
./anm.sh: line 265: syntax error near `&*#]'
./anm.sh: line 265: ` if [[ ! "$TITLE" =~ [a-zA-Z0-9 $%^\&*#] ]]; then RETURN="FAIL" && ERROR="ERROR: Title can only contain upper and lowercase letters, numbers, and spaces!"; return; fi'
4条答案
按热度按时间35g0bw711#
关于bash的
[[ ]]
构造,有几件重要的事情需要了解。第一个:[[
和]]
之间的词不进行分词和路径名扩展;执行波浪号扩展、参数和变量扩展、算术扩展、命令替换、进程替换和引号移除。第二件事:
一个额外的二元运算符,'= 0',是可用的,.操作符右边的字符串被认为是一个扩展的正则表达式,并相应地匹配.模式的任何部分都可以被引用,以强制将其作为字符串进行匹配。
因此,
=~
两侧的$v
将被扩展为该变量的值,但结果不会被字拆分或路径名扩展。换句话说,在左边不加引号的变量扩展是完全安全的,但是你需要知道变量扩展将发生在右边。所以如果你写:
[[ $x =~ [$0-9a-zA-Z] ]]
,右边的正则表达式中的$0
将在解释正则表达式之前被展开,这可能会导致正则表达式无法编译(除非$0
的展开以一个数字或标点符号结尾,其值小于数字)。如果你引用右边的[[ $x =~ "[$0-9a-zA-Z]" ]]
,那么右边将被视为普通字符串,而不是正则表达式($0
仍然会被扩展)。在这种情况下,您真正需要的是[[ $x =~ [\$0-9a-zA-Z] ]]
类似地,
[[
和]]
之间的表达式在解释正则表达式之前被拆分为单词。所以正则表达式中的空格需要转义或加引号。如果你想匹配字母、数字或空格,你可以使用:用途:[[ $x =~ [0-9a-zA-Z\ ] ]]
。其他字符同样需要转义,如#
,如果不加引号,将开始一个注解。当然,你可以把模式放到一个变量中:对于包含大量需要转义或引用以通过bash的lexer的字符的正则表达式,许多人更喜欢这种风格。但要注意:在这种情况下,你 * 不能 * 引用变量扩展:
最后,我认为你要做的是验证变量只包含有效的字符。执行此检查的最简单方法是确保它不包含无效字符。换句话说,就是这样一个表达式:
!
否定测试,将其转换为“不匹配”操作符,[^...]
正则表达式字符类表示“除...
之外的任何字符“。参数扩展和正则表达式操作符的组合可以使bash正则表达式语法“几乎可读”,但仍然存在一些问题。不是一直都有吗?一个是你不能把
]
放进$valid
,即使$valid
被引用,除非在一开始。(这是一个Posix正则表达式规则:如果你想在一个字符类中包含]
,它需要在开头。-
可以放在开头或结尾,所以如果你同时需要]
和-
,你需要以]
开头,以-
结尾,这会导致正则表达式“我知道我在做什么”表情:[][-]
)ygya80vv2#
如果有人想要一个使用变量的例子...
s4n0splo3#
我更喜欢使用
[:punct:]
。另外,a-zA-Z09-9
也可以是[:alnum:]
:q5iwbnjs4#
或者你可能会看到这个问题,因为你碰巧像我一样打了一个愚蠢的错字,把=~颠倒成了~=