用于匹配单词的正则表达式,除非前一行以单词结尾

时间:2017-09-01 14:12:02

标签: regex negative-lookbehind

我有一个包含许多句子的文本,用换行符和任意空格分隔:

Some thing.
  Some other text.
 Some line.
   Some additional text.
Some stuff.
    Some additional text.
Some additional text.

如何仅匹配那些前一行未以Something结尾的stuff个字词?

对于上面的例子,我会匹配这些词:

Some thing.           
  Some other text.          <-- skip, previous line ends with "thing."
 [Some] line.
   [Some] additional text.  
[Some] stuff.
    Some additional text.   <-- skip, previous line ends with "stuff."
[Some] additional text.

我试过了(?<!thing\.|stuff\.)[\r\n\s]+Some,但我不知道如何在负面的背后隐藏空格+换行符?我发现了一些使用\K来允许“变长”匹配的示例,但我显然不明白\K如何,因为我无法匹配任何内容。

2 个答案:

答案 0 :(得分:3)

您可以将“sacrificial match”与非捕获组匹配,以匹配您不想要的内容,然后匹配您在捕获组中所需的内容:

/(?:^\s*Some.*(?:thing\.|stuff\.)\s*^\s*Some)|(^\s*Some)/m

Demo

或者,如果你想要第一个和第四个(如评论中所述,你的例子是不一致的......)

/(?:(?:thing\.|stuff\.)\s*Some)|(^\s*Some)/m

Demo

或者,跳过第一个Some并包含第四个:

/(?:(?:thing\.|stuff\.)\s*Some)|((?<=\n)\s*Some)/m

Demo

此方法适用于大多数正则表达式。

背后的负面看法是这种情况下的问题,因为后面的外观需要固定宽度。您描述的\s*不是固定宽度。

答案 1 :(得分:1)

你可以使用PCRE动词(*SKIP)(*F)来破坏已知的matcha并在替换中使用你的匹配:

(?:thing|stuff)\.\R\s*\w+(*SKIP)(*F)|\bSome\b

here

此处(?:thing|stuff)\.\R\s*.*(*SKIP)(*F)将跳过&amp;上一行以thing.stuff.结尾时,匹配失败。在交替的右侧,我们将获得我们的匹配。