Good Day!
Insight would be much appreciated on the following...
The data below may or may not have the occurrence of the string 'tstp'. If 'tstp' doesn't occur, I'd like to populate the tstp_date and tst_time variables in the search below with the value 'foo'. Is it possible, in the context of a regular expression to assign 'foo' to my variables tstp_date and tstp_time if the string 'tstp' does not occur in the data?
My data looks like....
lease 1.2.3.4 {
starts 2 2014/11/11 05:47:49;
ends 2 2014/11/11 09:47:49;
tstp 2 2014/11/11 09:47:49;
cltt 2 2014/11/11 05:47:49;
binding state free;
hardware ethernet 60:33:4b:ce:83:1b;
uid "\001`3K\316\203\033";
}
lease 4.3.2.1 {
starts 2 2014/11/11 11:42:12;
ends 2 2014/11/11 15:42:12;
cltt 2 2014/11/11 11:42:12;
binding state active;
next binding state free;
hardware ethernet a4:c3:61:77:30:80;
uid "\001\244\303aw0\200";
}
My search...
...| rex "^.*?lease\s+(?<lease_ip>[\d\.]+) {\s+starts \d (?<start_date>\S+) (?<start_time>\S+?);\s+ends \d (?<ends_date>\S+) (?<ends_time>\S+?);\s+(?(?=tstp)tstp \d (?P<tstp_date>\S+) (?P<tstp_time>\S+)|)" | eval tstp_date=if(isnull(tstp_date),"foo",tstp_date)
My logic was to lookahead for the occurrence of 'tstp', if that exists, then capture tstp_date (e.g. 2014/11/11) and tstp_time (e.g. 09:47:49). If you note above, I added the eval to take care of null valued 'tstp_date' and 'tstp_time', but this is done outside the regex.
Thanks!
I think what you are trying to do is beyond the scope of regex. Your current approach is the best one.
As an aside, it's a little unusual that your tstp clause is written similarly to
(what i want|)
I think it's a little more idiomatic to do
(what i want)?
Also I think the leading ?
inside the group is a stray character?
I also believe the lookahead is unnecessary. You could just do
(tstp \d (?P<tstp_date>\S+) (?P<tstp_time>\S+))?
If tstp is not present, the clause won't match.
Agree jrodman - your suggestion is cleaner than what I was proposing. Thanks.
Other alternative to your eval could be "fillnull" command.
e.g.
your search with regex ...| fillnull value="foo" tstp_date
I think what you are trying to do is beyond the scope of regex. Your current approach is the best one.
Thanks - I wasn't sure if I had overlooked something 'regex-wise' that might have been useful.
Agreeing with Rich here, so promoting his comment to an answer.