1

我有一个像

HEADER foo bar
garbage
SUBHEADER foo foo bar
other garbage
SUBHEADER foo foo bar bar
HEADER foo baz
SUBHEADER foo bar foo foo
SUBHEADER foo foo foo foo
SOMETHING bar bar bar
HEADER baz baz
SUBHEADER baz bar baz foo

其中大写单词按字面意思出现并希望SOMETHING与相应的HEADERand一起查找SUBHEADER,即

HEADER foo baz
SUBHEADER foo foo foo foo
SOMETHING bar bar bar

这在程序中相当微不足道,但是正则表达式可以吗?我可以想象一个使用否定断言的解决方案,但这变得非常难以理解。

4

1 回答 1

2

如果您正在寻找最近的 HEADER 和 SUBHEADER 在某事之前,那么我认为您只希望在您的正则表达式中进行非贪婪匹配 - 假设您有一个正则表达式处理器可以一次匹配多行,这通常排除grepsed, 和类似的。

例如,像这样:

(^HEADER.*?$).*?(^SUBHEADER.*?$).*?(^SOMETHING.*?$)

我还假设 ' .' 确实匹配换行符(如在PCRE_DOTALLmode 中),并且 ' ^'/' $' 将匹配字符串中间的开始/行尾(如在PCRE_MULTILINEmode 中)。这些是许多正则表达式实现中的可配置选项。


编辑:我已经修改了您在评论中列出的命令并使其正常工作。

perl -0777 -ne '/.*(^HEADER.*?\n).*(^SUBHEADER.*?\n).*?(^SOMETHING.*?\n)/ms
  and print "$1$2$3*\n"'

(为了偏执,我添加了“m”标志并重新添加了行首锚点;如果你愿意,你可以把它们拿回来。)

关键的想法是在开头放置一个贪婪的全匹配模式,让正则表达式匹配器尽可能晚地匹配 HEADER。我本来希望像这样的非锚定匹配在开始时会表现得好像它有一个隐含的贪婪匹配,但显然在存在非贪婪运算符的情况下它不会那样工作。

于 2012-11-06T06:31:17.157 回答