关于bash,有几件重要的事情需要了解[[ ]]
结构。第一个:
在[[
和]]
; 执行波浪线展开、参数和变量展开、算术展开、命令替换、进程替换和引号删除。
第二件事:
还有一个附加的二进制运算符“=~”可用,。。。运算符右侧的字符串被视为扩展正则表达式,并相应地进行匹配。。。可以引用模式的任何部分以强制将其作为字符串进行匹配.
因此,$v(美元)
位于=~
将展开为该变量的值,但结果不会是word-split或pathname-expanded。换言之,在左侧不引用变量展开式是完全安全的,但您需要知道变量展开式将发生在右侧。
所以如果你写:[[$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]”如果[[$x=~$pat]];然后。。。
对于包含许多需要转义或引用才能通过bash的lexer的字符的正则表达式,许多人更喜欢这种风格。但请注意:在这种情况下,您不能引用变量展开:
#这不起作用:如果[[$x=~“$pat”]];然后。。。
最后,我认为您要做的是验证变量是否只包含有效字符。进行此检查的最简单方法是确保它不包含无效字符。换句话说,这样的表达:
valid='0-9a-zA-Z$%&#'#在列表中添加您想允许的其他内容如果[[!$x=~[^$有效]]];然后。。。
!
否定测试,将其转换为“不匹配”运算符[^...]
regex字符类表示“除...
".
参数扩展和正则表达式操作符的组合可以使bash正则表达式语法“几乎可读”,但仍然存在一些问题。(不是一直都有吗?)一个是你不能]
进入之内$有效
,即使$有效
被引用,除了一开始。(这是Posix正则表达式规则:如果您想包括]
在字符类中,它需要从开头开始。-
可以在开始或结束时进行,所以如果你需要两者]
和-
,您需要从开始]
并以结尾-
,导致正则表达式“我知道我在做什么”表情符号:[][-]
)