首页 > 解决方案 > 在 .NET 正则表达式中,将零宽度正前瞻断言与其他搜索词结合起来

问题描述

我需要解析具有多行标题、任意数量的多行详细信息和多行页脚的文件。每个细节都以图案开头,页脚以图案开头。假设每个细节都以“detail”开头,而footer以“footer”开头,我可以成功找到每个细节:(?s)detail.*?(?=(detail|footer)),然后是下一个细节或页脚。

我的问题是我希望一个正则表达式查找包含特定单词的详细信息,而另一个正则表达式查找不包含该单词的详细信息。第二个正则表达式不是问题,因为我正在遍历文件,如果在当前偏移处找不到第一个正则表达式,我会尝试第二个,这样第二个正则表达式就不需要指定“和不包含那个词”。

我知道我可以简单地使用(?s)detail.*?(?=(detail|footer)),然后查看该词是否在该匹配项中,但我正在使用一个不允许更改逻辑的现有框架。

我为第一个正则表达式所做的尝试导致匹配包含多个详细信息,直到找到包含该单词的匹配。如果在下一个“详细信息”或“页脚”之前未找到该单词,我将需要匹配失败。

例如,如果文件包含:

header bla bla
bla bla
detail one bla
bla bla
detail two bla
bla bla SpecialWord bla
footer
bla bla

当准备好找到第一个细节时,我希望第一个正则表达式失败,因为第一个“细节”和第二个“细节”之间没有 SpecialWord,第二个成功,返回:

detail one bla
bla bla

但是,我失败的尝试导致了正则表达式匹配:

detail one bla
bla bla
detail two bla
bla bla SpecialWord bla

如何制作一个以“detail”开头,在下一个“detail”或“footer”之前结束,并且在某个地方有 SpecialWord 的正则表达式?示例中的第一个细节会失败(因为 SpecialWord 不在第一个“细节”和第二个之间),而第二个细节会成功(因为 SpecialWord 在第二个“细节”和“页脚”之间。

任何帮助,将不胜感激。

标签: .netregex

解决方案


您可以匹配以详细信息开头的行。然后继续匹配所有不以详细信息或页脚开头或不包含 SpecialWord 的行。

然后匹配包含 SpecialWord 的行,然后是其他不以细节或页脚开头的行。

^detail\b.*(?:\r?\n(?!detail\b|footer\b|.*\bSpecialWord\b).*)*\r?\n.*\bSpecialWord\b.*(?:\r?\n(?!detail\b|footer\b).*)*

解释

  • ^线的开始
  • detail\b.*匹配细节和线路的其余部分
  • (?:非捕获组
    • \r?\n(?!detail\b|footer\b|.*\bSpecialWord\b).*如果不是以页脚细节开头或包含 SpecialWord,则匹配该行
  • )*关闭组并重复 0+ 次以匹配所有这些行
  • \r?\n.*\bSpecialWord\b.*匹配包含 SpecialWord 的行
  • (?:非捕获组
    • \r?\n(?!detail\b|footer\b).*如果不是以细节或页脚开头,则匹配该行
  • )*关闭组并重复 0+ 次以匹配所有这些行

.NET 正则表达式演示


推荐阅读