Linux BASH=~包含子字符串:“0”+&引用;或正则表达式字符行为

Linux BASH=~包含子字符串:“0”+&引用;或正则表达式字符行为,linux,bash,shell,command-line,escaping,Linux,Bash,Shell,Command Line,Escaping,想知道为什么以下内容不适用于角色:+ 字符“\”,”(“和”*“是有意义的,即*将扩展到当前目录中的文件夹/文件(在命令行shell扩展期间),类似地,\和(希望结束字符起作用,但我的理解是“+”应该像“-”那样工作 PS:我知道在IF语句中加双引号,即“${o}”将适用于下面测试用例中的所有字符。在IF语句中使用\${o}加双引号或不加双引号都会使所有检查失败 $ for o in - + \` ~ \~ , _ = / \\ ! @ \# $ \$ % ^ \& \* \( \);

想知道为什么以下内容不适用于角色:+

字符“\””(“”*“是有意义的,即*将扩展到当前目录中的文件夹/文件(在命令行shell扩展期间),类似地,\希望结束字符起作用,但我的理解是“+”应该像“-”那样工作

PS:我知道在IF语句中加双引号,即“${o}”将适用于下面测试用例中的所有字符。在IF语句中使用\${o}加双引号或不加双引号都会使所有检查失败

$ for o in - + \` ~ \~ , _ = / \\ ! @ \# $ \$ % ^ \& \* \( \); do a="a${o}b${o}c";if [[ $a =~ ${o} ]]; then echo "${o} exists in $a and =~ works"; else echo -e "\ncharacter ${o} doesn't work with =~\n"; fi; done
- exists in a-b-c and =~ works

character + doesn't work with =~

` exists in a`b`c and =~ works
/home/ubuntu exists in a/home/ubuntub/home/ubuntuc and =~ works
~ exists in a~b~c and =~ works
, exists in a,b,c and =~ works
_ exists in a_b_c and =~ works
= exists in a=b=c and =~ works
/ exists in a/b/c and =~ works

character \ doesn't work with =~

! exists in a!b!c and =~ works
@ exists in a@b@c and =~ works
# exists in a#b#c and =~ works
$ exists in a$b$c and =~ works
$ exists in a$b$c and =~ works
% exists in a%b%c and =~ works
^ exists in a^b^c and =~ works
& exists in a&b&c and =~ works

character * doesn't work with =~


character ( doesn't work with =~

) exists in a)b)c and =~ works

这个问题背后的基本误解是,
=~
是一个子字符串搜索运算符。它不是

=~
的右侧作为POSIX ERE表达式进行计算。
=~
因此是一个正则表达式匹配运算符,当右侧被引用以使其内容文字化时(或者当已知此字符串在解释为ERE时仅匹配自身时),该运算符经常用于搜索


+
在正则表达式中表示“1个或多个先前标记”--正如
*
表示“0个或多个先前标记”

因此,无论是
[[$foo=~+]
还是
[[$foo=~*]
都没有意义,因为它们检查的是之前根本不存在的标记的零个或多个

类似地,
在ERE中作为匹配组的开始和结束具有意义,因此当它们被赋予裸(unscaped/unquote)时,它们会导致一个无效的正则表达式

相反,如果引用扩展,则包含的所有字符都将被视为文字字符,而不是正则表达式元字符,从而产生预期的行为



如果要检查字符串中是否包含文字字符,请引用它--
[[$foo=~“$o”]
--或者使用全局样式模式:
[[$foo=*“$o”*]

这个问题背后的基本误解是
=
是一个子字符串搜索运算符。它不是

=~
的右侧作为POSIX ERE表达式进行计算。
=~
因此是一个正则表达式匹配运算符,当右侧被引用以使其内容文字化时(或者当已知此字符串在解释为ERE时仅匹配自身时),该运算符经常用于搜索


+
在正则表达式中表示“1个或多个先前标记”--正如
*
表示“0个或多个先前标记”

因此,无论是
[[$foo=~+]
还是
[[$foo=~*]
都没有意义,因为它们检查的是之前根本不存在的标记的零个或多个

类似地,
在ERE中作为匹配组的开始和结束具有意义,因此当它们被赋予裸(unscaped/unquote)时,它们会导致一个无效的正则表达式

相反,如果引用扩展,则包含的所有字符都将被视为文字字符,而不是正则表达式元字符,从而产生预期的行为



如果要检查字符串中是否包含文字字符,请引用它--
[[$foo=~“$o”]
--或者使用glob样式的模式:
[[$foo=*“$o”*]

否,
*
没有扩展到文件列表--在正则表达式中,它表示“前面的标记为零或多个”.@CharlesDuffy correct,我指的是“for”语句……但您正在将其转义为
\*
,用于
for
语句,因此它没有进行任何此类替换。顺便说一句,
^
的工作方式与您想象的不同。
[[hello=~^]]
是正确的,尽管
hello
中没有
^
,因为
^
是regex的“行的开始”。同样地,
$
表示行的结束。同意。我逃过了。很高兴知道with=~+?and*的工作方式类似于regex模式。我正在失去我的技能:)。如果不使用,我想知道是否有意思“如果我能使+或?字符起作用,则双引号,例如,${o}${o}在if语句中作为++或??使用,其中第一个字符+将作为literal,第二个字符将作为regex+或?或*。不,
*
并没有扩展到文件列表——在regex中,它意味着“前面的标记为零或更多”。@CharlesDuffy正确,我是指“for”语句……但您正在转义它,正如
\*
,对于
for
语句,因此它没有做任何这样的替换。顺便说一句,
^
的工作方式与您认为的不一样。
[[hello=~^]
是真的,尽管
hello
中没有
^
,因为
^
是regex的代言人。”行的开头“。同样,
$
用于行的结尾。同意。我逃过了它。很高兴知道使用=~+?和*就像正则表达式模式一样工作。我正在失去我的技能:)。如果不使用“双引号,我是否可以生成+或?字符工作,即IF语句中的${o}${o}作为++或??其中第一个字符+将是literal,第二个字符将作为regex+或?或*。