我在这里做错了什么?
尝试匹配包含空格,小写,大写或数字的任何字符串。特殊字符也会很好,但我认为这需要转义某些字符。
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'
答案 0 :(得分:125)
关于bash的[[ ]]
构造,有几个重要的事情需要了解。第一个:
不对
[[
和]]
之间的字词执行单词拆分和路径名扩展;执行代码扩展,参数和变量扩展,算术扩展,命令替换,进程替换和引用删除。
第二件事:
另一个二元运算符'=〜'可用,...运算符右侧的字符串被视为扩展正则表达式并相应匹配... 模式的任何部分都可以引用强制它匹配为字符串。
因此,$v
两侧的=~
将扩展为该变量的值,但结果不会是分词或路径名扩展。换句话说,在左侧保留变量扩展是非常安全的,但是您需要知道变量扩展将在右侧发生。
因此,如果您编写:[[ $x =~ [$0-9a-zA-Z] ]]
,则在解释正则表达式之前,右侧正则表达式中的$0
将被展开,这可能会导致正则表达式无法编译(除非扩展$0
以数字或标点符号结尾,其ascii值小于一位数。 如果您引用右侧的[[ $x =~ "[$0-9a-zA-Z]" ]]
,那么右侧将被视为普通字符串,而不是正则表达式($0
仍然会被扩大)。在这种情况下,您真正想要的是[[ $x =~ [\$0-9a-zA-Z] ]]
同样,[[
和]]
之间的表达式在解释正则表达式之前被拆分为单词。因此正则表达式中的空格需要被转义或引用。如果您想匹配字母,数字或空格,可以使用:[[ $x =~ [0-9a-zA-Z\ ] ]]
。其他字符同样需要进行转义,例如#
,如果没有引用则会启动评论。当然,您可以将模式放入变量中:
pat="[0-9a-zA-Z ]"
if [[ $x =~ $pat ]]; then ...
对于包含大量字符的正则表达式,需要通过bash的词法分析器进行转义或引用,很多人都喜欢这种风格。但要注意:在这种情况下,不能引用变量扩展:
# This doesn't work:
if [[ $x =~ "$pat" ]]; then ...
最后,我认为你要做的是验证变量只包含有效字符。执行此检查的最简单方法是确保它不包含无效字符。换句话说,这样的表达式:
valid='0-9a-zA-Z $%&#' # add almost whatever else you want to allow to the list
if [[ ! $x =~ [^$valid] ]]; then ...
!
否定测试,将其变为“不匹配”运算符,[^...]
正则表达式字符类表示“...
以外的任何字符”。
参数扩展和正则表达式运算符的组合可以使bash正则表达式语法“几乎可读”,但仍然存在一些问题。 (不是总是存在吗?)一个是你无法将]
放入$valid
,即使引用$valid
,除非在开头。 (这是一个Posix正则表达式规则:如果你想在一个字符类中包含]
,它需要在开头。-
可以在开头或结尾,所以如果你需要两个{ {1}}和]
,您需要从-
开始,以]
结束,从而导致正则表达式“我知道我在做什么”表情符号:-
)
答案 1 :(得分:11)
如果有人想要一个使用变量的例子......
#!/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
答案 2 :(得分:10)
我更愿意使用[:punct:]
。此外,a-zA-Z09-9
可能只是[:alnum:]
:
[[ $TEST =~ ^[[:alnum:][:blank:][:punct:]]+$ ]]
答案 3 :(得分:0)
或者您可以像我一样做一个愚蠢的错字,然后将=〜反转为〜=