velpandian
velpandian

Reputation: 471

How to match the ip address using regular expression from the given string?

Let consider i have the follwing string:

set a {example192.168.0.1example10.0.0.1example172.16.0.1}

From of the above string i want to match 10.0.0.1 using regexp?

for first ip we can do by regexp {.*?(\d+\.\d+\.\d+\.\d+)} $a match sub1

puts $sub1 = 192.168.0.1

for last ip we can do by regexp {.*?(\d+\.\d+\.\d+\.\d+)$} $a match sub1

puts $sub1 = 172.16.0.1

for second ip we can do by regexp {.*?(\d+\.\d+\.\d+\.\d+).*?(\d+\.\d+\.\d+\.\d+)} $a match sub1 sub2

puts $sub2 = 10.0.0.1

  1. Is that any simple format for for match second ip using regexp?

  2. For example, Let consider in a string i have 100 IP address, from this string how can i match the 10th IP address using regular expression

Upvotes: 0

Views: 5586

Answers (2)

egorulz
egorulz

Reputation: 1505

Do you want to check only for IP4 addresses or IPV6 as well? The regex in that case will be crazy long and look something like this:

[list {(((25[0-5])|(2[0-4]\d)|(1\d\d)|(0?\d?\d))\.((25[0-5])|(2[0-4]\d)|(1\d\d)|(0?\d?\d))\.((25[0-5])|(2[0-4]\d)|(1\d\d)|(0?\d?\d))\.((25[0-5])|(2[0-4]\d)|(1\d\d)|(0?\d?\d))(/((3[0-2])|([1-2]?\d)))?)} \
                      {(((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?(/((12[0-8])|(1[0-1]\d)|(0?\d?\d)))?)}]

Upvotes: 0

nurdglaw
nurdglaw

Reputation: 2127

Try

% set a {example192.168.0.1example10.0.0.1example172.16.0.1}
example192.168.0.1example10.0.0.1example172.16.0.1
% set ipAddrs [regexp -inline -all {\d+\.\d+\.\d+\.\d+} $a]
192.168.0.1 10.0.0.1 172.16.0.1
% set ipAddr [lindex $ipAddrs 1]
10.0.0.1

Note that Tcl lists index from 0, so to obtain the 10th IP address in your hypothetical example, you'd need [lindex $ipAddrs 9]

Also, I've removed the leading .*? and the parentheses from your regex pattern. There doesn't seem to be any need explicitly to match leading non-IP address text, and the parentheses caused each IP address to appear twice in the list, making it harder to remove the desired address.

Upvotes: 1

Related Questions