155

我在这里做错了什么?

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

TEST=“这是一个带有一些数字12345和特殊字符*&^%$#的测试标题”如果[[“$TEST”=~[a-zA-Z0-9\]]];然后是BLAH;fi(菲涅耳)

这显然只测试上限、下限、数字和空格。但不起作用。

更新

我想我应该说得更具体一些。下面是实际的代码行:

如果[[“$TITLE”=~[a-zA-Z0-9$%^\&*#]]];然后RETURN=“FAIL”&&ERROR=“ERROR:标题只能包含大小写字母、数字和空格!”;fi(菲涅耳)

这就是错误:

./anm.sh:第265行:条件表达式中的语法错误./anm.sh:第265行:“&*#]”附近的语法错误./anm.sh:第265行:`if[[!“$TITLE”=~[a-zA-Z0-9$%^\&*#]];然后RETURN=“FAIL”&&ERROR=“ERROR:标题只能包含大小写字母、数字和空格!”;回报;fi’
5
  • 您实际使用的是哪个shell/垃圾箱/垃圾箱/bin/bash/垃圾箱/csh? 评论 2013年9月10日2:48
  • 12
    将正则表达式放在变量中更安全。re='。。。不管……”;[[$string=~$re]](没有引号——这是极少数情况下,他们会破坏没有引号就可以工作的东西)。 评论 2013年9月10日3:49
  • 5
    改为在作业周围加单引号。双引号无法正确保护特殊字符。
    – 三人组
    评论 2013年9月10日4:10
  • 许多查尔斯!不把它放在变量中还是可以的,但它绝对不能被引用!例如:[[$var=~.*]]用于匹配正则表达式.*(任何内容)。我想如果你使用引号,引号本身就被认为是正则表达式的一部分…
    – 斯特芬
    评论 2017年4月19日23:20
  • 14
    我发现了一个总结:(1.)使用单引号将模式保存在变量中模式=“^hello[0-9]*$”(2.)如果需要正则表达式匹配,请不要引用模式因为引用DISABLES表示正则表达式模式匹配。(即表达式[[“$x”=~$pattern]]将使用regex和表达式进行匹配[[“$x”=~“$pattern”]]禁用正则表达式匹配,相当于[[“$x”==“$pattern”]]). 评论 2017年10月16日15:18

4个答案4

重置为默认值
271

关于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正则表达式规则:如果您想包括]在字符类中,它需要从开头开始。-可以在开始或结束时进行,所以如果你需要两者]-,您需要从开始]并以结尾-,导致正则表达式“我知道我在做什么”表情符号:[][-])

13
  • 11
    我只是想指出“!~是”“不匹配”“运算符”不是真的。任意使用如果![[$x=~$y]]如果[[!$x=~$y]]
    – 酒精
    评论 2015年6月1日7:48
  • shellchecker不同意。。。SC2076:不要引用rhs of=~,它将按字面意思匹配,而不是作为正则表达式。 评论 2016年12月9日20:12
  • 4
    @莱纳德:这与我的声明“你不能引用变量展开式”和注释“这不起作用”有何不同?对此还有什么不清楚的地方? 评论 2016年12月10日4:35
  • 1
    @jinbeomhong:表达式本身像往常一样用空格分隔成单词。但参数和命令扩展不是字分割。 评论 2020年6月13日21:15
  • 1
    @金伯洪:我没有说任何与bash手册不同的东西。[[]]”从程序文本中解析出来,就像将命令行解析为单词一样。不过,与命令行不同的是,单词在展开后不会被拆分。 评论 2020年6月14日11:34
60

如果有人想要一个使用变量的例子。。。

#!/垃圾桶/垃圾桶#仅对“开发”或“发布/*”分支继续BRANCH_REGEX=“^(开发$|release//*)”如果[[$BRANCH=~$BRANCH_REGEX]];然后echo“BRANCH“$BRANCH”与BRANCH_REGEX“$BRONCH_REGEX”匹配”其他的echo“BRANCH'$BRANCH'不匹配BRANCH_REGEX'$BRONCH_REGX'”fi(菲涅耳)
1
  • 我想补充一点,如果你这样做,你必须使用一个变量,只需如果[[$BRANCH=~“^(开发$|release//*)”]]行不通。
    – 唐老鸭
    评论 2023年12月4日11:47
14

我想用[:打孔:]为了这个。也,a-zA-Z09-9型可能只是[:铝:]:

[[$TEST=~^[[:alnum:][:空白:][:穿孔:]]+$]]
7

或者你可能会看到这个问题,因为你碰巧像我一样犯了一个愚蠢的错误,并且将=~颠倒为~=

2
  • 似乎模式必须至少以^以美元符号结尾$为了工作。这是唯一的方法,这样得到的真值对我来说是正确的。(???) 评论 2021年5月31日7:12
  • 我仍然在javascript中犯了这个错误 评论 2021年8月21日2:46

你的答案

单击“发布您的答案”,表示您同意我们的服务条款并确认您已阅读我们的隐私政策.

不是你想要的答案吗?浏览标记的其他问题问你自己的问题.