I am using a regex pattern to match the dhcp leases data file.
(?mis)^lease\s (\S )(?:(?!^lease\s).)*?binding state\s (active|inactive|offline|free|abandoned?).*?(\w{2}:\w{2}:\w{2}:\w{2}:\w{2}:\w{2});.*?vendor-class\s*(\"[^\"] \");.*?[^}]
But the above regex is not matching properly. For example if I have a example dhcp.leases file in below format.
lease 000.000.00.001 {
starts 1 2022/04/25 17:31:27;
ends 1 2022/04/25 17:33:27;
cltt 1 2022/04/25 17:31:27;
binding state free;
hardware ethernet LL:KK:JJ:HH:DD:SS;
uid "SDS";
vendor-class "test1";
set vendor-class-identifier = "test1";
client-hostname "MNOP";
}
lease 000.000.00.002 {
starts 3 2022/04/27 14:41:30;
ends 3 2022/05/04 14:41:30;
cltt 3 2022/04/27 14:41:30;
binding state active;
next binding state free;
rewind binding state free;
hardware ethernet MM:NN:DD:SS:RR:WW;
uid "SASa";
client-hostname "ADBC";
}
lease 000.001.00.003 {
starts 3 2022/04/20 18:22:44;
ends 5 2022/05/20 18:22:44;
cltt 3 2022/04/20 18:22:44;
binding state active;
next binding state free;
rewind binding state free;
hardware ethernet AA:BB:CC:DD:FF:FF;
uid "dasdad";
vendor-class "test 3 vendor";
set vendor-class-identifier = "test3";
}
Here In the second lease I am not having vendor-class filed which I am using in regex, so instead of skipping the vendor-class filed its trying to match the same in third lease, because of that I am getting only 2 match groups instead of 3 match groups. its merging 2nd and 3rd lease as one lease. Please help me out. Please find the below link for better understanding: https://regex101.com/r/dFCWk1/1
CodePudding user response:
You can use
(?mis)^lease\s (\S )(?:(?!^lease\s).)*?binding state\s (active|inactive|offline|free|abandoned?)(?:(?!^lease\s).)*?(\w{2}:\w{2}:\w{2}:\w{2}:\w{2}:\w{2})(?:(?:(?!^lease\s).)*?vendor-class\s*(\"[^\"] \").*?\s*(\"[^\"] \");)?[^}]*
See the regex demo
Details:
- Replace all
.*?
but last with the tempered greedy token,(?:(?!^lease\s).)*?
, to avoid the section overflow during a match - Make sure the vendor matching pattern part is optional, see the
(?:(?:(?!^lease\s).)*?vendor-class\s*(\"[^\"] \").*?\s*(\"[^\"] \");)?
pattern, where the(?:(?!^lease\s).)*?vendor-class\s*(\"[^\"] \").*?\s*(\"[^\"] \");
is wrapped with the optional non-capturing group (see How do I make part of a regex match optional?)