匹配文本直到某些字符不包括它们

时间:2017-11-07 17:31:51

标签: regex

这是一个示例文本:

E) RWY 09R/27L DUE 
RUNWAY 
ALERT FGF
F)xxx
G)xxx

我需要匹配E行后的文本,直到F)不包括它。 但问题是有时候F)线可能不存在,那么我需要匹配直到G)。此外,这些都不会出现。 到目前为止,我尝试了这样的正则表达式:

E\)\s*([^(?:F\)|G\))]*).*

我认为它有效,但如果我在E行的文字中有G或F字母,那么它会在那里切割它。什么可以解决方案?

1 个答案:

答案 0 :(得分:1)

如果您正在使用PCRE(似乎就是这样),您可以使用positive lookahead断言来限制.*的匹配:

(?s)E\)\s*(.*(?=F\))|.*(?=G\)))

我们使用DOTALL激活(?s)模式后(您也可以使用s修饰符),点.现在匹配(也)新线,将在\1之后和E)之后的完整文本或F)之后和E)之前的完整文本捕获到第一组G)。请参阅demo here

如果您还想要处理F)G)都不存在的情况,可以添加第三个案例$作为锚点(字符串断言的零宽度结束) :

(?s)E\)\s*(.*(?=F\))|.*(?=G\))|.*$)

原始正则表达式不起作用,因为范围[^F)|G)]将匹配范围中未指定的任何字符的第一个匹配项(例如a)。在|中使用时,几乎所有元字符(如[..])都会失去其特殊含义(仅^-处理不同)。

更简单的替代方案(没有前瞻性)是:

(?s)E\)\s*(.*F\)|.*G\))

但其中包括捕获组F)中的结尾G)\1