pradeepk6
pradeepk6

Reputation: 53

regex block contains

I have a config file:

config line 1
....
config line n
router mk1
 ip 10.1.1.2
 deviceType t1
 sub config line!
 sub config line 2
 !more sub config
!
 !!!
more config lines
router mk2
 ip 10.1.1.2
 sub config line1
 sub config line 2
 deviceType t2
!

Each router block starts with the word router on a new line and ends with ! on a new line. A config file can contain many router blocks.Each sub-block begins with a single space.The lines in sub-block can be in any order.I want to select a block that contains a specific line for eg: deviceType t2.

So far I could identify all the router blocks with the following:

(?ms)^router mk.*?^!$

But I only need a block that contains the line deviceType t2

Upvotes: 0

Views: 208

Answers (3)

Cary Swoveland
Cary Swoveland

Reputation: 110695

The following regular expression should work for most all regex engines (though it may be necessary to replace \R with \r?\n). I tested it with the PCRE (PHP) regex engine.

(?m)^router .+\R(?: .*\R)* deviceType t2\R(?: .*\R)*!$

Start your engine!

The engine performs the following operations.

(?m)            : multiline mode (^ and $ match beginning and end of line)
^               : match start of line
router .*\R     : match line beginning 'router ', including terminator
(?: .*\R)*      : match a line including terminator that begins with a
                  space in a non-capture group, execute 0+ times
deviceType t2\R : match line 'deviceType t2', including terminator
(?: .*\R)*      : match a line including terminator that begins with a
                  space in a non-capture group, execute 0+ times
!$              : match the line '!'

Upvotes: 1

user13469682
user13469682

Reputation:

don't wurry boute line endings, most engines have multi-line mode

try (?m)^router.*\s*(?:^(?!!).*\s*)*?^\s*deviceType\s+t2.*\s*(?:^.*\s*)*?^!

uses fewest steps, yes ?

demo

Upvotes: 1

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 627022

You may use

(?m)^router mk\d+(?:\R(?!router mk\d+$).*)*?\R\s*deviceType t2(?:\R.*)*?\R!$
(?m)^router mk\d+(?:\n(?!router mk\d+$).*)*?\n\s*deviceType t2(?:\n.*)*?\n!$
(?m)^router mk\d+(?:\r?\n(?!router mk\d+$).*)*?\r?\n\s*deviceType t2(?:\r?\n.*)*?\r?\n!$

See the regex demo. The variations are for different kinds of line break sequences, \R matches any line break, \n only matches LF line endings, and \r?\n matches CRLF or LF line endings.

Details

  • (?m) - MULTILINE mode on
  • ^ - line start
  • router mk\d+ - router mk and 1+ digits
  • (?:\R(?!router mk\d+$).*)*? - 0 or more occurrences, but as few as possible, of the following sequence of patterns:
    • \R(?!router mk\d+$) - a line break sequence not followed with router mk + one or more digits at the end of a line
    • .* - any 0 or more chars other than line break chars, as many as possible
  • \R\s* - a line break sequence and then 0+ whitespaces
  • deviceType t2 - a literal string
  • (?:\R.*)*?
  • \R - line break sequence
  • ! - !
  • $ - end of line.

Upvotes: 1

Related Questions