Regex Lookahead 根据缩进文本进行匹配

Regex Lookahead to match based on indented text

如果在下面的缩进行中有另一个定义的文本(这里是"switchport mode access"),我想匹配以特定字符串开头的行(在这个例子中是"interface")。

示例数据:

interface GigabitEthernet1/0/1
 description abc
 bla
 switchport mode access
 xyz
 abc
interface GigabitEthernet1/0/2
interface GigabitEthernet1/0/3
 xyz
 abc
interface GigabitEthernet1/0/4
 description Test
 switchport mode access
 xyz
 abc
interface GigabitEthernet1/0/5
 description

应该匹配:

interface GigabitEthernet1/0/1
interface GigabitEthernet1/0/4

我试过了:

interface GigabitEthernet1\/0\/[0-9](?=(\n|.)*switchport mode access)

但这会检查接口下的所有行,所以它确实匹配:

interface GigabitEthernet1/0/1
interface GigabitEthernet1/0/2
interface GigabitEthernet1/0/3
interface GigabitEthernet1/0/4

我怎样才能让前瞻只在有一行不以空格开头时才起作用?

使用以下正则表达式后捕获第 1 组的内容:

(interface GigabitEthernet.*)(?:(?!interface GigabitEthernet)[\s\S])*switchport mode access

Click for Demo

解释:

  • (interface GigabitEthernet.*) - - 匹配 interface GigabitEthernet 后跟出现 0 次以上的任何字符,直到换行符,并在第 1 组
  • 中捕获整个匹配项
  • (?:(?!interface GigabitEthernet)[\s\S])* - 匹配出现次数超过 0 次且不以子字符串 interface GigabitEthernet
  • 开头的任何字符
  • switchport mode access - 匹配 switchport mode access

您可以使用这种基于前瞻性的表达式,只有当它后跟 switchport mode access 而中间没有出现 interface GigabitEthernet 时,它才会匹配您想要的字符串,

interface GigabitEthernet1.*(?=(?:(?!interface GigabitEthernet1)[\w\W])*switchport mode access)

interface GigabitEthernet1.* 仅当其后跟 switchport mode access 时才会匹配到行尾,而在使用 (?=(?:(?!interface GigabitEthernet1)[\w\W])*switchport mode access) 正向预测 [=] 之间没有出现 interface GigabitEthernet1 20=]

Demo

编辑:感谢 Anubhav 在评论中提出的关于性能更好的正则表达式的建议,

^interface GigabitEthernet1\/0\/[0-9](?=(?:(?!\ninterface GigabitEthernet1\/0\/[0-9])[\s\S])*switchport mode access)

Faster regex as suggested by Anubhava