5

I've tried to extract only IP addresses from the the given example input, but it extracts some text with it. Here's my code:

$spfreccord="v=spf1 include:amazonses.com include:nl2go.com include:smtproutes.com include:smtpout.com ip4:46.163.100.196 ip4:46.163.100.194 ip4:85.13.135.76 ~all";

 $regexIpAddress = '/ip[4|6]:([\.\/0-9a-z\:]*)/';        
 preg_match($regexIpAddress, $spfreccord, $ip_match);
 var_dump($ip_match);

I'm looking to match only the IPv4 IP address xxx.xxx.xxx.xxx in each column of the table, but it looks like that the $regexIpAddress is not correct.

Can you please help me find the correct regex to extract only the IPv4 IP addresses? Thanks.

Will
  • 24,082
  • 14
  • 97
  • 108
  • Tried `/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/`? – Thamilhan Jun 05 '16 at 10:40
  • yeh it work just fine but one little problem is that i cannot extract cidr class v=spf1 ip4:205.201.128.0/20 ip4:198.2.128.0/18 ?all is it possible to extract the cidr 205.201.128.0/20 – salaheddine Rmaili Jun 05 '16 at 10:44
  • Then change it to: `/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(?:\/\d{2})?/` – Thamilhan Jun 05 '16 at 10:56
  • Hi @Will you answer is working fine but i don't need to extract the text "ip4" with the ips, Hi @Thamilan your answer is working good for me but one problem is that i cannot extract classes cidr like this `198.2.128.0/18` so please if there is something to add to my ipregex to extract also cidr like this example `198.2.128.0/18` thanks all – salaheddine Rmaili Jun 05 '16 at 11:02
  • @sala.eddi mine doesn't extract the text, just the IPs. Look at the output in my example. – Will Jun 05 '16 at 11:10
  • Hi Will yes but it extract reccord like this ip4:94.176.182.0 i don't need to extract ip4 beside i need to extract cidr classes like this 198.2.128.0/18, Thanks any way that was very helpful from you HI @Thamilan your answer is the good answer for my question bcause it give me classes and unique ips address thanks a lot – salaheddine Rmaili Jun 05 '16 at 11:27

2 Answers2

6

Use the following regex:

/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(?:\/\d{2})?/

So for this:

$spfreccord="v=spf1 include:amazonses.com include:nl2go.com include:smtproutes.com include:smtpout.com ip4:46.163.100.196 ip4:46.163.100.194 ip4:85.13.135.76 cidr class v=spf1 ip4:205.201.128.0/20 ip4:198.2.128.0/18 ~all";

 $regexIpAddress = '/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(?:\/\d{2})?/';        
 preg_match_all($regexIpAddress, $spfreccord, $ip_match);
 var_dump($ip_match);

Gives:

array(1) {
  [0]=>
  array(5) {
    [0]=>
    string(14) "46.163.100.196"
    [1]=>
    string(14) "46.163.100.194"
    [2]=>
    string(12) "85.13.135.76"
    [3]=>
    string(16) "205.201.128.0/20"
    [4]=>
    string(14) "198.2.128.0/18"
  }
}
Thamilhan
  • 13,040
  • 5
  • 37
  • 59
1

You want preg_match_all(), and a slight modification of your regex:

php >  $regexIpAddress = '/ip4:([0-9.]+)/';
php >  preg_match_all($regexIpAddress, $spfreccord, $ip_match);
php >  var_dump($ip_match[1]);
array(3) {
  [0]=>
  string(14) "46.163.100.196"
  [1]=>
  string(14) "46.163.100.194"
  [2]=>
  string(12) "85.13.135.76"
}
php >

You don't need to match against a-z; it's not a valid part of an IP address, 4 or 6. Since you said you only want IPv4, I've excluded any matching of IPv6 addresses.

If you wanted to include IPv6 as well, you can do this:

php > $regexIpAddress = '/ip[46]:([0-9a-f.:]+)/';
php > preg_match_all($regexIpAddress, $spfreccord, $ip_match);
php > var_dump($ip_match[1]);
array(4) {
  [0]=>
  string(14) "46.163.100.196"
  [1]=>
  string(14) "46.163.100.194"
  [2]=>
  string(12) "85.13.135.76"
  [3]=>
  string(39) "2001:0db8:85a3:0000:0000:8a2e:0370:7334"
}
Will
  • 24,082
  • 14
  • 97
  • 108