Difficulty with using backreferences/capture groups in find/replace.
-
I have a regex that matches any IPv4 Address in a router’s BGP summary output and everything from “Established” and beyond. This is to isolate the AS number, and then ideally replace the text to the left of it with a router command, and the text to the right of it with more specific arguments for said command.
My find regex:(((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\s+)(\s+Established.*)
My replace regex (not working as I expect):
?1show ip bgp neighbor ?2 statistics detail
Example output
Neighbor AS Number Status Time Accepted Rejected Sent Queued 1.2.3.4 12345 Established 0d 8h 56m 4823 982 1 0
What I want to happen:
show ip bgp neighbor 12345 statistics detail
What actually happens:
show ip bgp neighbor statistics detail12345
I did some reading on the docs for regex replacement and I can’t quite figure out what I’m doing wrong. Any help/clarification is much appreciated!
-
Is your “Example output” section is really supposed to be example input?
If so, I can’t get your regex to match it.
Your use of
?1
and?2
in the replace is confusing; probably you want\1
or my preference of${1}
(and of course\2
or${2}
for the second one).Otherwise, hard to say, but I’m sure someone else will come along and put some time into it. :-)
-
@Alan-Kilborn
The row above the IP address are just the names of the columns, not intending to match on those. And my apologies, was missing the|
before the “Established” capture group:(((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\s+)|(\s+Established.*)
And the issue with using the referenced notation is it doesn’t replace the full IP address before it for some reason. If I use either \n or ${n} then I get this:
1.2.3.4 show ip bgp neighbor 3. statistics detail12345show ip bgp neighbor statistics detail
My notation is likely wrong, I’m not programmer or regex master. But I’m essentially trying to say “From beginning of line to whitespace after IP address, replace with X. Then, from whitespace before “Established” and to the end of the line, replace with Y.”
Hope that makes sense, thanks for taking a look. -
@James-Norton said in Difficulty with using backreferences/capture groups in find/replace.:
But I’m essentially trying to say “From beginning of line to whitespace after IP address, replace with X. Then, from whitespace before “Established” and to the end of the line, replace with Y.”
I’m not sure why you need such a complicated regex just to identify the IP address, unless you have many and only want to work on defined ranges that might occur. A more generalised regex for IP address is
\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}
and as you state “…that matches any IPv4 Address…” I would think my regex should suffice.A possible solution might be (using the Replace function)
Find What:(?-s)^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\x20+)(\d+\x20)(\x20+Established.*)
Replace With:show ip bgp neighbor \2 statistics detail
I could have even removed the
(
and)
around the portions we don’t need as we don’t return those in the replacement.Terry
-
Hello, @james-norton, @alan-kilborn, @terry-r and All,
BTW, note that there’s an important difference between :
-
To search for
IPV4
addresses, in a file containing validIVP4
addresses, only -
To search for valid
IPV4
addresses, in a file which may contain some non validIPV4
addresses !
In the first case, as the @terry-r’s solution, simply use the almost obvious regex
\b(\d{1,3}\.){3}\d{1,3}\b
In the second cas, use one of the two regexes, below :
-
(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(*FAIL)|\b((?1)\.){3}(?1)\b
-
(?(DEFINE)(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d))\b((?1)\.){3}(?1)\b
Notes :
-
In the first regex, once the part
(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)
is stored as group1
, the(*FAIL)
control verb discards this match but this regex part can be re-used with the syntax(?1)
. Then, the second alternative\b((?1)\.){3}(?1)\b
does match a validIPV4
address ! -
The second regex uses a special conditional syntax with the key expression
(DEFINE)
. which stores, as above, the part25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d
, between parentheses, but which is never matched, by definition. So the effective regex is just the part\b((?1)\.){3}(?1)\b
, coming next, which match validIPV4
addresses only
Best Regards,
guy038
-