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 detailExample output
Neighbor AS Number Status Time Accepted Rejected Sent Queued 1.2.3.4 12345 Established 0d 8h 56m 4823 982 1 0What I want to happen:
show ip bgp neighbor 12345 statistics detailWhat actually happens:
show ip bgp neighbor statistics detail12345I 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
?1and?2in the replace is confusing; probably you want\1or my preference of${1}(and of course\2or${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 detailMy 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 detailI 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
IPV4addresses, in a file containing validIVP4addresses, only -
To search for valid
IPV4addresses, in a file which may contain some non validIPV4addresses !
In the first case, as the @terry-r’s solution, simply use the almost obvious regex
\b(\d{1,3}\.){3}\d{1,3}\bIn 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)\bdoes match a validIPV4address ! -
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 validIPV4addresses only
Best Regards,
guy038
-