shell脚本奇怪的正则表达式

Posted

技术标签:

【中文标题】shell脚本奇怪的正则表达式【英文标题】:shell script odd regex 【发布时间】:2016-06-06 06:08:03 【问题描述】:

我有一些正则表达式在我的 shell 脚本中表现得很奇怪regex101,这是样本的样子

fname="direcheck"
FIND="*"
if [[ $fname =~ $FIND ]]; then
echo "no quotes"
fi

if [[ "$fname" =~ "$FIND" ]]; then
echo "with quotes"
fi

现在它什么也不会显示 如果我将查找更改为

FIND="[9]*"

然后它不打印引号 如果我说

FIND="[a-z]*"

然后它不打印引号

如果我说

FIND="dircheck"

然后什么都没有打印出来

如果我说

FIND="*ck"

然后什么都没有打印出来

我不明白这个正则表达式是如何工作的

如何使用这些变量,正确的语法是什么

【问题讨论】:

【参考方案1】:

**ck 是无效的正则表达式。如果您与== 进行比较,而不是=~,它会起作用(不带引号)。如果您想为它们使用在== 中获得的相同功能,等效的正则表达式是.*.*ck

[9]*9 的任意数量(包括零)字符。你的direcheck 中有零个字符9,所以它匹配。 (由 Brainfart 编辑,感谢 chepner)

direcheck 中找不到dircheck,因此不打印任何内容不足为奇。

[a-z]* 是介于 az 之间的任意数量的字符(即任意数量的小写字母)。这将匹配,假设它没有被引用。

【讨论】:

@ritesht93:是的,第一点。全局是==,正则表达式是=~ 也不要混淆glob=~正则表达式 严格来说*是一个有效的正则表达式;它匹配包含星号的字符串。如果没有要修改的标记,星号就失去了作为量词的特殊含义,而只是一个星号。例如,printf 'one*\ntwo\n' | grep '*'. @ghoti:方言不同。在 bash 方言中,这是不正确的:[[ '*' =~ * ]] && echo yep || echo nope 说“不”。在 Ruby 的 Oniguruma 方言、Perl 的 PCRE 方言和 javascript 的方言中,/*/ 是语法错误。诚然,Ruby、Perl 和 JS 在这里是无关紧要的;但grep 也一样。 正则表达式不会锚定到它们匹配的字符串的开头或结尾。 [9]*[a-z]* 都成功匹配空字符串,它是 any 参数的子字符串。【参考方案2】:

我终于弄明白了,为什么它的工作如此奇怪

[a-z]* 和 [9]* 和 [anythinghere]* 它们都匹配,因为它匹配零次或多次。所以“direcheck”有 [9] 零次或多次。

所以

 if [[ "$fname" =~ $FIND ]]; then

 if [[ $fname =~ $FIND ]]; then

都是正确的,并且

if [[ "$fname" =~ "$FIND" ]]; then

仅当字符串完全匹配时才匹配,因为 $FIND 匹配为文字字符串而不是正则表达式

【讨论】:

以上是关于shell脚本奇怪的正则表达式的主要内容,如果未能解决你的问题,请参考以下文章

shell脚本编程之正则表达式(扩展正则表达式sed)

shell脚本——正则表达式Sed与Awk文本处理工具详解

如何在 shell 脚本中使用正则表达式?

shell脚本之正则表达式

Shell脚本——正则表达式

正则表达式和Shell脚本。