简体   繁体   中英

Perl regular expression split help needed

I'm trying to split records like these

123.45.67.89/24 - String - Other string details (/25-/30)

into 3 variables containing "123.45.67.89","24" and "String - Other string details (/25-/30)"

#!/usr/bin/perl -w

use Data::Dumper;

$file = "Network_Usage.clean";

open (Network_Usage,$file);

while (<Network_Usage>) {
        chomp;
        my $row = $_;
        my @array = $row =~ /((([0-9]{1,3})\.{0,1}){4})\/([0-9]{1,2}) - (.*)/;
        print Dumper ( @array);
        exit;
}

close (Network_Usage);

But I'm getting this result :

root@host:~/# ./split.pl 
$VAR1 = '123.45.67.89'; 
$VAR2 = '89'; 
$VAR3 = '89'; 
$VAR4 = '24'; 
$VAR5 = '';

Event if it is doing the job for me ( I can use $VAR1,4,5 ). I would like to know what am I doing wrong to receive the results in $VAR2/3 .

The easiest solution I can find is to limit the result, so only let the split() to work twice:

my @arr = split /[\/\s-]+/, $s, 3

It yields:

0  '123.45.67.89'
1  24
2  'String - Other string details (/25-/30)'

You can keep this from capturing the 89 twice by using non-capturing groups. Just add a ?: to the beginning of the group that you do not want to capture. Try changing your regex to the following:

/((?:(?:[0-9]{1,3})\.{0,1}){4})\/([0-9]{1,2}) - (.*)/
   ^  ^

This regex would work:

([0-9]{1,3}[\.]?[0-9]{1,3}[\.]?[0-9]{1,3}[\.]?[0-9]{1,3}[\.]?)\/([\d]+) - (.*)

Working regex example:

http://regex101.com/r/sC2uN3

Matches:

MATCH 1
1.  `123.45.67.89`
2.  `24`
3.  `String - Other string details (/25-/30)`

Perhaps you can do use this in your regex matching:

#!/usr/bin/perl

use warnings;
use strict;

my $t="123.45.67.89/24 - String - Other string details (/25-/30)";

if ($t =~ /(\d+\.\d+\.\d+\.\d+)\/(\d+)\s+(.*)/){
    print "$1\n"; #Prints "123.45.67.89"
    print "$2\n"; #Prints "24"
    print "$3\n"; #Prints "- String - Other string details (/25-/30)"
}

If - and / are always the record separators, you could also use the split function:

my $filename = "Network_Usage.clean";
open (my $network_file, '<', $file);

while (my $row = <$network_file>) {
        chomp;
        my @array = split /[\/\s-]/, $row; 
        print Dumper @array;
}

close($network_file);

A couple points on style:

  1. it is typical to assign the $row inside of the while condition
  2. BAREWORD filehandles are usually discouraged

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM