带有开始和结束词的多行正则表达式

Multiline Regex with opening and closing word

我得承认,如果涉及到 RegEx 表达式,我是非常基础的。 我有一个用 C# 编写的应用程序,它在文本文件中查找某些正则表达式。我不确定如何解释我的问题,所以我将直接举例。

我的文字:

   DeviceNr : 30
     DeviceClass = ABC
     UnitNr = 1
     Reference = 29
     PhysState = ENABLED
    LogState = OPERATIVE
     DevicePlan = 702
     Manufacturer = CDE
     Model = EFG
    ready
    
    DeviceNr : 31
     DeviceClass = ABC
     UnitNr = 9
     Reference = 33
     PhysState = ENABLED
    LogState = OPERATIVE
     Manufacturer = DDD
     Model = XYZ
    Description = something here
    ready

我需要匹配以“DeviceNr”字样开头、以“ready”结尾并具有“DeviceClass = ABC”和“Model = XYZ”的多行文本 - 我只能假设这些行将在此确切的顺序,但我不能假设它们之间会有什么,甚至不能假设它们之间的其他行数。我尝试使用以下正则表达式,但它匹配了整个文本,而不仅仅是 DeviceNr : 31

DeviceNr : ([0-9]+)(?:.*?\n)*? DeviceClass = ABC(?:.*?\n)*? Model = XYZ(?:.*?\n)*?ready\n\n

问题是您要匹配 'DeviceNr : 31' 后跟 'DeviceClass = ABC'(可能有一些中间字符)然后是 'Model = XYZ'(同样可能有一些中间字符)然后是 'ready'(同样可能有一些中间字符)确保这些中间字符中的 none 实际上是另一个 'DeviceNr' 部分的开始 .

因此,为了将任意中间字符与上述强制执行相匹配,我们可以使用以下正则表达式,该表达式使用了负先行断言

(?:(?!DeviceNr)[\s\S])*?
  1. (?: - 非捕获组的开始
  2. (?!DeviceNr) - 断言输入的下一个字符不是 'DeviceNr'
  3. [\s\S] - 匹配空白或非空白字符,即 any 字符
  4. )非捕获组结束
  5. *?非贪婪匹配0个或多个字符只要下一个输入不匹配'DeviceNr'

那么重复使用上面的正则表达式就很简单了,如下:

DeviceNr : (\d+)\n(?:(?!DeviceNr)[\s\S])*?DeviceClass = ABC\n(?:(?!DeviceNr)[\s\S])*?Model = XYZ\n(?:(?!DeviceNr)[\s\S])*?ready

See Regex Demo

捕获组 1 将具有 DeviceNr 值。

重要提示

上面的正则表达式在执行所需的步骤数方面非常昂贵,因为它必须在匹配 DeviceNr : (\d+).

后检查几乎每个字符位置的否定前瞻断言

如果您知道 "DeviceClass = ABC" and "Model = XYZ" 存在并按此顺序,您还可以在每行基础上使用先行断言,首先匹配所有不包含的行,例如 DeviceNr

然后匹配匹配的行,对 Modelready

也这样做
^\s*DeviceNr : ([0-9]+)(?:\r?\n(?!\s*DeviceClass =).*)*\r?\n\s*DeviceClass = ABC\b(?:\r?\n(?!\s*Model =).*)*\r?\n\s*Model = XYZ\b(?:\r?\n(?!\s*ready).*)*\r?\n\s*ready\b
  • ^ 字符串开头
  • \s*DeviceNr : ([0-9]+) 匹配 DeviceNr : 并在 组 1
  • 中捕获 1+ 个数字 0-9
  • (?:非捕获组
    • \r?\n(?!\s*DeviceClass =).*匹配一个换行符,断言该行不包含DeviceClass =
  • )* 关闭非捕获组并可选择重复,因为您不知道有多少行
  • \r?\n\s*DeviceClass = ABC\b 匹配一个换行符,可选的空白字符和 DeviceClass = ABC
  • (?:\r?\n(?!\s*Model =).*)*\r?\n\s*Model = XYZ\b 之前的做法也适用于Model =
  • (?:\r?\n(?!\s*ready).*)*\r?\n\s*ready\bready
  • 相同的方法

Regex demo

请注意,\s 也可以匹配换行符。如果你想防止这种情况,你也可以使用 [^\S\r\n] 来匹配没有换行符的空白字符。

Regex demo