Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Referencing a Backreference

by dru145 (Friar)
on Mar 14, 2002 at 16:17 UTC ( [id://151718]=perlquestion: print w/replies, xml ) Need Help??

dru145 has asked for the wisdom of the Perl Monks concerning the following question:

Monks,

I the follwing text:
192.168.89.1 acmeorp.acme.com 192.168.31.3 ftp.acme.com 192.168.19.179 [Unknown]
I'm caputuring the ip and servername into separate arrays. Here is my regex that does this:
push (@ips, $1) if /\b(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\b/; push (@names, $1) if /\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b\s{2,}(\w[ +^\s]*|\[Unknown\])\s{2}/;
My question is, is there a way to reference the ip match in my regex that matches the server name? I thought this would work, but it doesn't:
#push (@names, $1) if /$1\s{2,}(\w[^\s]*|\[Unknown\])\s{2}/;


Thanks,
Dru
Another satisfied monk.

Replies are listed 'Best First'.
Re: Referencing a Backreference
by gav^ (Curate) on Mar 14, 2002 at 16:26 UTC
    Wouldn't something like this be a lot simpler?
    my @ips = (); my @names = (); while (<DATA>) { chomp; my ($ip, $name) = split /\s+/, $_, 2; push @ips, $ip; push @names, $name; } use Data::Dumper; print Dumper(\@ips, \@names); __DATA__ 192.168.89.1 acmeorp.acme.com 192.168.31.3 ftp.acme.com 192.168.19.179 [Unknown]

    gav^

      Wouldn't something like this be a lot simpler?

      So true, but it can be done even simpler!

      my (@ips, @names); while (<DATA>) { my ($ip, $name) = split; push @ips, $ip; push @names, $name; }
      split with no arguments is like split ' ', $_, which in turn has a special meaning because of the chr(32) string. I think you can asume ip adresses and hostnames do not contain whitespace...

      If order and duplicates are not very important, a hash would be really nice:
      my %hash = map split, <DATA>; my @ips = keys %hash; my @names = values %hash;

      U28geW91IGNhbiBhbGwgcm90MTMgY
      W5kIHBhY2soKS4gQnV0IGRvIHlvdS
      ByZWNvZ25pc2UgQmFzZTY0IHdoZW4
      geW91IHNlZSBpdD8gIC0tIEp1ZXJk
      

        Not such a big deal here unless it's a huge log being parsed, but probably generally not the best generic scheme.

        --
        perl -pe "s/\b;([st])/'\1/mg"

Re: Referencing a Backreference
by PrimeLord (Pilgrim) on Mar 14, 2002 at 16:54 UTC
    This solution is along the same lines as gav's but with slightly less typing.

    while (<DATA>) { chomp; push @ips, (split)[0]; push @names, (split)[1]; }


    Also I am a little confused on your question. If you are looking for a way to seperate the data, but still access server name by IP address you could always just write the info into a hash.

    my %ips_names; while (<DATA>) { $ips_names{(split)[0]} = (split)[1]; }


    Then you can access just the portion of the data you need, but they are still tied together. Sorry if that wasn't actually what you were looking for.

    -Prime

    Update: Sigh. Juerd beat me to it again. :) Although my code is still shorter ;)
Re: Referencing a Backreference
by dru145 (Friar) on Mar 14, 2002 at 17:07 UTC
    Well, there is actually more that I'm matching on. This is just a portion of it. Here is a little more background if you are interested Splitting Across Multiple Lines. I tried for two days trying to split on this text, but could not come up with a good solution. Regex work better for me in this case.

    I appreciate the suggestions, but I'm still wondering if there is a way to reference the regex like I'm trying to do.

    Thanks,
    Dru
    Another satisfied monk.
      put the ip in a variable.
      Update:The error was actually in the original regex given not properly matching the names, as far as I can tell, but i think it's much more readable to use a variable name instead of $1, which I think looks confusing and non-intuitive inside of a pattern match.
      #!/usr/bin/perl -w use strict; my @addrs = ( "192.168.89.1 acmeorp.acme.com", "192.168.31.3 ftp.acme.com", "192.168.19.179 [Unknown]" ); my (@ips,@names); for (@addrs) { push (@ips, $1) if /\b(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\b/; my $ip = $1; push (@names, $1) if /\Q$ip\E\s+([\w.]+[^\s]*$|\[Unknown\])\s*?/; } print @names;

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://151718]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chilling in the Monastery: (4)
As of 2024-04-26 08:03 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found