在先匹配另一个模式后,如何在 2 个模式之间打印文本?

Han*_*loo 2 text-processing regular-expression

想象一下如下所示的一行:

Some text with MATCH1_TEXT some other text and MATCH2_TEXT until MATCH3_TEXT
Run Code Online (Sandbox Code Playgroud)

我想在这行有唯一的搜索MATCH1_TEXT,并找到文本之间 MATCH2_TEXTMATCH3_TEXT

在上面的例子中,我想得到until(在之前和之后的空格字符直到)。

ica*_*rus 5

例如与 sed

sed -n 's/^.*MATCH1_TEXT.*MATCH2_TEXT\(.*\)MATCH3_TEXT.*$/\1/p'
Run Code Online (Sandbox Code Playgroud)

假设匹配的文本在一行中按顺序最多只出现一次。

如果MATCH1_TEXT可能出现在行中的任何位置,那么另一种看待问题的方法是忽略任何没有它的行,因此程序就变成了

sed -n '/MATCH1_TEXT/!d;s/.*MATCH2_TEXT\(.*\)MATCH3_TEXT.*$/\1/p'
Run Code Online (Sandbox Code Playgroud)

如果MATCH2_TEXT可以发生不止一次,例如输入是

 text MATCH1_TEXT stuff MATCH2_TEXT and MATCH2_TEXT until MATCH3_TEXT
Run Code Online (Sandbox Code Playgroud)

那么问题是需要什么输出,until或者and MATCH2_TEXT until?类似的问题适用于 MATCH3_TEXT 的重复副本。这些可以用稍微复杂的 sed 程序来处理。例如保持最长的字符串

sed -n '/MATCH1_TEXT/!d;/MATCH2_TEXT.*MATCH3_TEXT/!d;s/MATCH2_TEXT/\n/;s/^.*\n\(.*\)MATCH3_TEXT.*$/\1/p'
Run Code Online (Sandbox Code Playgroud)

它的工作原理是首先拒绝任何不合适的行,然后将第一次出现的 MATCH2_TEXT 更改为换行符(行中永远不会有换行符),然后选择换行符和 MATCH3_TEXT 之间的文本。

一些语言,例如perlpython已经扩展了正则表达式中可用的操作以允许“最小匹配”,这在这些情况下可能有所帮助但不是必需的。sed有条件地循环的能力比正则表达式更强大。