Grep:星号 (*) 并不总是有效

Tra*_*rae 15 command-line bash regex grep

如果我 grep 包含以下内容的文档:

ThisExampleString

...对于表达式This*Stringor *String,不返回任何内容。但是,This*按预期返回上述行。

表达式是否用引号括起来没有区别。

我认为星号表示任意数量的未知字符?为什么它只有在表达式的开头才有效?如果这是预期的行为,我应该使用什么来代替表达式This*String*String

Ser*_*nyy 23

正则表达式中的星号表示“匹配前面的元素 0 次或更多次”。

在你的特殊情况下grep 'This*String' file.txt,你试图说,“嘿,grep,匹配我这个词Thi,然后是s零次或多次小写,然后是这个词String”。在s中找不到小写字母Example,因此 grep 忽略ThisExampleString

在 的情况下grep '*String' file.txt,您是在说“grep,匹配我的空字符串 - 字面上没有 - 在单词之前String”。当然,这不是ThisExampleString应该如何阅读。(还有其他可能的含义——你可以在有和没有-E标志的情况下尝试这个——但没有一个意思是你在这里真正想要的。)

明知.是指“任何单个字符”,我们可以这样做:grep 'This.*String' file.txt。现在 grep 命令将正确读取它:This后跟重复任意次数的任何字符(将其视为 ASCII 字符的选择),然后是String.

  • pabouk 是对的,文件名扩展发生在命令运行之前;比较`strace grep .* file.txt |& head -n 1` 和`strace grep '.*' file.txt |& head -n 1`。实际上`grep` 也适用于任何Unicode 字符(例如`echo -ne ⇏ | grep ⇏` 输出`⇏`) (11认同)
  • 有趣的是(并且对于故障排除非常讨厌:) 事情是像 `grep This.*String file.txt` 这样的命令通常会起作用,因为很可能不会有与 shell 通配符表达式 `This.*String` 匹配的文件。在这种情况下,默认情况下 Bash 将按字面意思传递包含 `*` 的参数。 (7认同)
  • 在 Bash(和大多数 Unix shell)中,`*` 是一个特殊字符,它应该被引用或转义,例如:`grep 'This*String' file.txt` 或这样:`grep This\*String file .txt` 不会对意外结果感到惊讶。 (6认同)
  • @pabouk 在 shell 中,`*` 是一个通配符。在 grep 中,`*` 是一个正则表达式运算符。见 http://unix.stackexchange.com/q/57957/70524 (2认同)

kos*_*kos 9

*在BRE元字符1个S,ERE 1秒和PCRE 1 S匹配0或多个正好先前分组图案的(如果是分组图案前述*元字符),前一个字符类的0或多个正好(如果字符类是在*元字符之前)或前一个字符出现 0 次或多次(如果在元字符之前既没有分组模式也没有字符类*);

这意味着在This*String模式中,作为*元字符前面没有分组模式或字符类,*元字符匹配前一个字符(在本例中为s字符)的0 次或多次出现:

% cat infile               
ThisExampleString
ThisString
ThissString
% grep 'This*String' infile
ThisString
ThissString
Run Code Online (Sandbox Code Playgroud)

要匹配任何字符的 0 次或多次出现,您需要匹配.匹配任何字符的元字符的0 次或多次出现:

% cat infile               
ThisExampleString
% grep 'This.*String' infile
ThisExampleString
Run Code Online (Sandbox Code Playgroud)

*BREs 和 EREs 中的元字符总是“贪婪的”,即它将匹配最长的匹配:

% cat infile
ThisExampleStringIsAString
% grep -o 'This.*String' infile
ThisExampleStringIsAString
Run Code Online (Sandbox Code Playgroud)

这可能不是理想的行为;如果不是,您可以打开grep的 PCRE 引擎(使用该-P选项)并附加?元字符,将其放在*+元字符之后会改变它们的贪婪性:

% cat infile
ThisExampleStringIsAString
% grep -Po 'This.*?String' infile
ThisExampleString
Run Code Online (Sandbox Code Playgroud)

1:基本正则表达式、扩展正则表达式和Perl兼容正则表达式


小智 5

在这里找到的解释之一链接

星号“ *”在正则表达式中与通配符中的含义不同;它是应用于前面的单个字符或表达式(例如 [0-9])的修饰符。星号匹配它前面的零个或多个。因此[A-Z]*匹配任意数量的大写字母,包括无,而[A-Z][A-Z]*匹配一个或多个大写字母。