2

Stack Overflow RegEx Wizards, I've scoured Google and haven't quite found a good solution for this. I need to pull out 1:N DNS servers from IPCONFIG results. In the example below, I would need the first three. However, there may be an instance where there are more or less.

Update: Optimally we want to place cursor at first colon(:) in the DNS string then capture IPs until we hit an alpha character. So if we can just scrape a string from that colon to that alpha character we can run another RegEx to match IPs.

DNS.*: gets us to the first colon (:)

Need to read-ahead until alpha character.

Important Note: Because of the third-party tool we're using we can only use RegEx :)

Here's the RegEx value I've been using as for IPs. This will capture all IP's instead of just the DNS ones...

(([0-9]){1,3}.){1,3}[0-9]{1,3}

IPCONFIG Example

    Subnet Mask . . . . . . . . . . . : 255.255.255.0
    Default Gateway . . . . . . . . . : 152.225.244.1
    DHCP Server . . . . . . . . . . . : 10.204.40.57
    DNS Servers . . . . . . . . . . . : 10.204.127.11
                                        10.207.2.50
                                        10.200.10.6
    Primary WINS Server . . . . . . . : 10.207.40.145
    Secondary WINS Server . . . . . . : 10.232.40.38
    Lease Obtained. . . . . . . . . . : Tuesday, August 28, 2012 6:45:12 AM
    Lease Expires . . . . . . . . . . : Sunday, September 02, 2012 6:45:12 A
pixelbobby
  • 4,368
  • 5
  • 29
  • 49
  • Updated post to answer your question. (Java or Pearl5) Thanks. – pixelbobby Aug 30 '12 at 16:41
  • Why would you accept an IP address with 2 or 3 octets? That is, the middle `{1,3}` quantifier should be just `{3}` because IPv4 addresses in normal form are always 4 octets. – tripleee Aug 30 '12 at 17:01

5 Answers5

2
#!/usr/bin/env perl

use strict;
use warnings;

my $data = <<END;
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . : 152.225.244.1
DHCP Server . . . . . . . . . . . : 10.204.40.57
DNS Servers . . . . . . . . . . . : 10.204.127.11
                                    10.207.2.50
                                    10.200.10.6
Primary WINS Server . . . . . . . : 10.207.40.145
Secondary WINS Server . . . . . . : 10.232.40.38
Lease Obtained. . . . . . . . . . : Tuesday, August 28, 2012 6:45:12 AM
Lease Expires . . . . . . . . . . : Sunday, September 02, 2012 6:45:12 A
END

my @ips = ();

if ($data =~ /^DNS Servers[\s\.:]+((\d{2}\.\d{3}\.\d{1,3}\.\d{1,3}\s*)+)/m) {
    @ips = split(/\s+/, $1);
    print "$_\n" foreach(@ips);
}
David
  • 6,462
  • 2
  • 25
  • 22
  • +1 hey :) we're not using perl script just perl compatible RegEx. I was able to use your RegEx string!! Beautiful green checkmark most likely cometh. – pixelbobby Aug 30 '12 at 17:36
  • @pixelbobby Ok - well, just consider the surrounding script a "proof of concept" :-) – David Aug 30 '12 at 17:38
  • 1
    @pixelbobby I just noticed that I forgot to escape the third period. I just updated the solution with the correction – David Aug 30 '12 at 18:37
0

I would use unpack instead of regular expressions for parsing column-based data:

#!/usr/bin/env perl

use strict;
use warnings;

while (<DATA>) {
    my ($ip) = unpack 'x36 A*';
    print "$ip\n";
}

__DATA__
DNS Servers . . . . . . . . . . . : 10.204.127.11
                                    10.207.2.50
                                    10.200.10.6
Primary WINS Server . . . . . . . : 10.207.40.145
Secondary WINS Server . . . . . . : 10.232.40.38

You may have to adjust the number 36 to the actual number of characters that should be skipped.

Alan Haggai Alavi
  • 72,802
  • 19
  • 102
  • 127
  • Sorry it's not perl it's RegEx. The software we use says it's compatible with RegEx Java and RegEx Perl. Thanks so much for this though... just wish we could use it. – pixelbobby Aug 30 '12 at 16:56
0

Match

DNS.+?:(\s*([\d.]+).)+

and pull out the groups. This assumes you have the entire multi-line string in one blob, ans that the extracted text may contain newlines and other whitespace. The last dot is to match the newline, you need to use /m option

Gabber
  • 5,152
  • 6
  • 35
  • 49
  • Hey thanks for your post. This however only pulls out the first line and IP address. It doesn't reach the second or third ones. I believe I need a way to capture a string between the colon : and the first alpha. Then I can RegEx that and get IPs. – pixelbobby Aug 30 '12 at 17:01
0

Personally, I'd go in a different direction. Instead of manually parsing the output of ipconfig, I'd use the Win32::IPConfig module. Win32::IPConfig - IP Configuration Settings for Windows NT/2000/XP/2003

use Win32::IPConfig;
use Data::Dumper;

my $host = shift || "127.0.0.1";
my $ipconfig = Win32::IPConfig->new($host);

my @searchlist = $ipconfig->get_searchlist;
print Dumper \@searchlist;
Ron Bergin
  • 1,070
  • 1
  • 6
  • 7
  • I think he mentioned it isn't actually Perl code he is using, so sadly, SPAN is out – DVK Aug 30 '12 at 17:11
0

Match against this regex (see in action):

DNS Servers.*:\s*(.*(?:[\n\r]+\s+.*(?:[\n\r]+\s+.*)?)?)

First capture group will be your three IP's (atmost three) as you requested. You need to trim whitespaces surely.

Edit: Regex fixed to match at most three IP's. If there is less IP's, matches them only.

mmdemirbas
  • 9,060
  • 5
  • 45
  • 53
  • This supposes you know there are from one to three servers, and will grab three arbitrary lines if you have fewer than three servers. Fixing it to only match IP addresses would correct these issues, though. – tripleee Aug 30 '12 at 17:30
  • Wow you're so close. The IRS blocks your link -- sorry. This appears to be only matching the first 2 IPs. If I can just get a single capture group from the : to the start of the word "Primary" we're good to go! – pixelbobby Aug 30 '12 at 17:30
  • @tripleee How I missed this. Fixing soon :) – mmdemirbas Aug 30 '12 at 17:39
  • @pixelbobby Fixed. Please try and give me feedback. – mmdemirbas Aug 30 '12 at 17:52