Bash正则expression式如果语句

我在这里做错了什么?

尝试匹配任何包含空格,小写,大写或数字的string。 特殊字符也不错,但我认为这需要转义某些字符。

TEST="THIS is a TEST title with some numbers 12345 and special char *&^%$#" if [[ "$TEST" =~ [^a-zA-Z0-9\ ] ]]; then BLAH; fi 

这显然只testing上,下,数字和空格。 虽然没有工作。

*更新*

我想我应该更具体一些。 这是实际的代码行。

 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' 

关于bash的[[ ]]构造有几件重要的事情要知道。 首先:

字符分割和path名扩展不在[[]]之间的单词上执行; 代字符扩展,参数和variables扩展,算术扩展,命令replace,进程replace和报价移除。

第二件事:

另外一个二元运算符'=〜'是可用的,…运算符右边的string被认为是一个扩展的正则expression式,并相应匹配… 模式的任何部分可能被引用来强制匹配作为一个string

因此, =~两侧的$v将被扩展为该variables的值,但结果不会被分词或path名扩展。 换句话说,在左侧引用可变扩展是完全安全的,但是您需要知道可变扩展会在右侧发生。

所以如果你写了: [[ $x =~ [$0-9a-zA-Z] ]] ,右边的正则expression式中的$0将在parsing正则expression式之前展开,这可能会导致正则expression式编译失败(除非$0的扩展以数字或ascii值小于一个数字的标点符号结尾)。 如果你引用右边的这样的话,右边将被当作一个普通的string,而不是正则expression式 (和$0仍然会被扩展)。 你真正想要的是[[ $x =~ [\$0-9a-zA-Z] ]]

类似地,在解释正则expression式之前, [[]]之间的expression式被分割成单词。 所以正则expression式中的空格需要被转义或引用。 如果您想匹配字母,数字或空格,您可以使用[[ $x =~ [0-9a-zA-Z\ ] ]] 。 其他字符同样需要转义,比如# ,如果没有引用就会开始注释。 当然,你可以把模式变成一个variables:

 pat="[0-9a-zA-Z ]" if [[ $x =~ $pat ]]; then ... 

对于包含很多需要通过bash的词法分析器进行转义或引用的字符的正则expression式,许多人更喜欢这种风格。 但要小心:在这种情况下,你不能引用variables扩展:

 # This doesn't work: if [[ $x =~ "$pat" ]]; then ... 

最后,我想你要做的是validationvariables只包含有效的字符。 检查最简单的方法是确保它不包含无效字符。 换句话说,像这样的expression:

 valid='0-9a-zA-Z $%&#' # add almost whatever else you want to allow to the list if [[ ! $x =~ [^$valid] ]]; then ... 

! 否定testing,把它变成一个“不匹配”的运算符,而一个[^...]正则expression式字符类的意思是“除...之外的任何字符”。

参数扩展和正则expression式运算符的组合可以使bash正则expression式语法“几乎可读”,但是仍然有一些问题。 (不是总是有的吗?)一个是你不能把$valid ,即使$valid的报价,除了在一开始。 (这是一个Posix的正则expression式规则:如果你想包括]在一个字符类,它需要在开始-可以在开始或结束,所以如果你需要]- ,你需要开始]并以-结尾,导致正则expression式“我知道我在做什么”表情: [][-]

我宁愿使用[:punct:] 。 另外, a-zA-Z09-9可能只是[:alnum:]

 [[ $TEST =~ ^[[:alnum:][:blank:][:punct:]]+$ ]] 

如果有人想使用variables的例子…

 #!/bin/bash # Only continue for 'develop' or 'release/*' branches BRANCH_REGEX="^(develop$|release//*)" if [[ $BRANCH =~ $BRANCH_REGEX ]]; then echo "BRANCH '$BRANCH' matches BRANCH_REGEX '$BRANCH_REGEX'" else echo "BRANCH '$BRANCH' DOES NOT MATCH BRANCH_REGEX '$BRANCH_REGEX'" fi