grep正则表达式解决方案(贪婪不起作用)

grep正则表达式解决方案(贪婪不起作用)

我的 data.txt 文件中有以下文本

:MENU1
0. public
1. admin
2. webmail

:SYNTAX
! opt1, ... :

:ERROR1
Error #1, blah... blah.. blah...
Please do ...

:ERROR2
Error #2 ...

我想使用正则表达式(PERL 语法)将部分提取到:MENU1下一个第一个:,但从结果中删除MENU1最后一个。:

一直在尝试几个正则表达式,但在我得到的最接近的解决方案中,我无法使用“贪婪”选项,也无法丢弃最后一个“:”

grep -Poz "^:MENU1\K[\w\W]*:"

这适用于 grep ...
但将所有文本带到最后一个“:”...
我只想直到下一个“:”之后:MENU1

0. public
1. admin
2. webmail
 

(注意最后的空行)

答案1

该模式*:将匹配所有内容,直到最后一个:。停在下一个:你需要的地方*?:。例如:

% grep -Poz '^:MENU1\K[\w\W]*?:' data.txt 

0. public
1. admin
2. webmail

:

您可以通过匹配 . 之前的换行符来删除第一行\K。例如:

% grep -Poz '^:MENU1\n\K[\w\W]*?:' data.txt 
0. public
1. admin
2. webmail

:

要吃空行和:您可以匹配并丢弃该文本。例如:

% grep -Poz '^:MENU1\n\K[\w\W]*?(?=\n+:)' data.txt 
0. public
1. admin
2. webmail

接下来我们可以简化您的角色类,以匹配除以下内容之外的任何内容:

% grep -Poz '^:MENU1\n\K[^:]*?(?=\n+:)' data.txt 
0. public
1. admin
2. webmail

最后我们可以重写比赛的初始部分:

% grep -Poz '(?<=:MENU1\n)[^:]*?(?=\n+:)' data.txt 
0. public
1. admin
2. webmail

这与 @terdon 的想法类似,但是这可以处理空白行,而无需再次调用 grep。

最终的正则表达式利用环视四周断言。这(?<=pattern)是一个look-behind断言,可让您匹配pattern但不将其包含在输出中。这(?=pattern)是一个look-ahead断言,让我们可以匹配尾随模式,而不将其包含在输出中。

答案2

关于什么:grep -Poz "^:MENU1\K[^:]*"

答案3

@Herbert 的解决方案可能是最简单的,但您也可以使用环视:

$ grep -Poz '(?<=:MENU1\n)[^:]*' file 
0. public
1. admin
2. webmail
  

相关内容