Reputation: 21
I have some string in a text file.
line con 0
session-timeout 10
exec-timeout 10 0
privilege level 15
logging synchronous
login authentication console-in
transport preferred none
stopbits 1
line vty 0 4
session-timeout 30
exec-timeout 30 0
logging synchronous
transport preferred none
transport input ssh
transport output ssh
line vty 5 15
session-timeout 10
exec-timeout 10 0
logging synchronous
transport preferred none
transport input ssh
transport output ssh
I'm trying find/match
session-timeout 10
exec-timeout 10
only under the line con 0
with Regex.
line con 0.*\n(.*\n)*.*session-timeout 10.*\n(.*\n)*.*exec-timeout 10
will also catch
vty 5 15
session-timeout 10
exec-timeout 10
Is there a way to do better?
Upvotes: 1
Views: 103
Reputation: 163207
If the 2 lines session-timeout 10
and exec-timeout 10
should occur in that order, you can use 2 capture groups.
Per capture group value, make sure that the lines that precede it do not cross matching either line
and for example session-
for the first match and exec-
for the second match using a negative lookahead.
^line con 0(?:\r?\n(?!line | session-).*)*\r?\n[\p{Zs}\t]*(session-timeout 10).*(?:\r?\n(?!line| exec-).*)*\r?\n[\p{Zs}\t]*(exec-timeout 10)\b
^
Start of stringline con 0
Match literally(?:\r?\n(?!line | session-).*)*
Match all lines that do not start with line
or session-
\r?\n[\p{Zs}\t]*
Match a newline and optional spaces or tabs(session-timeout 10)
Capture group 1, match literally (or use [0-9]+
to match 1+ digits).*
Match the rest of the line(?:\r?\n(?!line| exec-).*)*
Match all lines that do not start with line
or exec-
\r?\n[\p{Zs}\t]*
Match a newline and optional spaces or tabs(exec-timeout 10)
Capture group 2, match literally\b
A word boundary to prevent a partial matchSee a regex 101 demo and a .NET regex demo(Click on the "Table" tab to see the groups)
Upvotes: 1
Reputation: 9865
It is because greedy behavior which is the default behavior of regex matching (it tries to expand the match as much as possible while matching the pattern). Adding ?
after quantifiers +
or *
solves the problem of greediness.
Therefore use the pattern:
line con 0.*?\n(.*?\n)*?.*?session-timeout 10.*?\n(.*?\n)*?.*?exec-timeout 10
Which tries to match as few lines as possible.
It matches
line con 0
session-timeout 10
exec-timeout 10
Upvotes: 0