1

I want to match lines that start with a specific string (in this example "interface") if there is a another defined text (here "switchport mode access") in the following indented lines.

Example data:

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

Should match:

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

I tried:

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

But this checks all the lines below an interface, so it does match:

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

How can I make the lookahead only work until there is a line that doesnt start with a whitespace?

whateverrest
  • 178
  • 3
  • 11

2 Answers2

4

You can use this look ahead based expression that will match your desired string only if it is followed by switchport mode access without interface GigabitEthernet appearing in between,

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

interface GigabitEthernet1.* matches till end of line only if it is followed by switchport mode access while there is no occurrence of interface GigabitEthernet1 in between using (?=(?:(?!interface GigabitEthernet1)[\w\W])*switchport mode access) positive look ahead

Demo

Edit: Thanks to Anubhav's suggestion in comments for even a better performing regex,

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

Faster regex as suggested by Anubhava

Pushpesh Kumar Rajwanshi
  • 18,127
  • 2
  • 19
  • 36
  • 2
    ++ to make it even faster use: `^interface GigabitEthernet1\/0\/[0-9](?=(?:(?!\ninterface GigabitEthernet1\/0\/[0-9])[\s\S])*switchport mode access)` – anubhava Mar 19 '19 at 06:54
  • 2
    @anubhava: Thanks Anubhav, that's a considerate improvement almost double the speed. I appreciate your input for improving my answer :) – Pushpesh Kumar Rajwanshi Mar 19 '19 at 06:56
3

Capture the contents of Group 1 after using the following regex:

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

Click for Demo

Explanation:

  • (interface GigabitEthernet.*) - Tempered Greedy Token - matches interface GigabitEthernet followed by 0+ occurrences of any character until the newline character and captures this whole match in group 1
  • (?:(?!interface GigabitEthernet)[\s\S])* - matches 0+ occurrences of any character that does not begin with the sub-string interface GigabitEthernet
  • switchport mode access - matches switchport mode access
Gurmanjot Singh
  • 10,224
  • 2
  • 19
  • 43