Regex to get string until certain string in Perl

Viewed 232

I have a string and I want to extract certain part of the string using regex.

Below is my script. I could able to get the expected output. But need to know do we have any alternative way to achieve this.

#!/usr/bin/perl

use strict; use warnings;

my $str = "Network=ABC,Network=10,Node=N360,Slot=3,Unit=R1,Group=RU,DeviceSet=1,Device=2";

if($str =~ m/(.*),Device/){
    print "Out: $1";
} else {
    print "Not matching";
}

If the string contains Device=<anydigit> at the end, then it should not print Device=<anydigit> and rest everything it should print. I am doing this using (.*) expression. Apart from this any alternative we have?

4 Answers

I'd tackle it like this:

#!/usr/bin/perl

use strict; 
use warnings;

use Data::Dumper;

my $str = "Network=ABC,Network=10,Node=N360,Slot=3,Unit=R1,Group=RU,DeviceSet=1,Device=2";

my @field_order = ( $str =~ m/(\w+)=/g);
my %value_of = ($str =~ m/(\w+)=(\w+)/g);

print Dumper \%value_of;

print "Contains Device of $value_of{'Device'}\n" if defined $value_of{'Device'};

pop ( @field_order ) if ( $field_order[-1] eq "Device" ); #discard trailing 'Device' field. 

print Dumper \@field_order;


#Splice together your hash, without including 'Device' on the end. 
print join ",", map { $_ . "=". $value_of{$_}  } @field_order;

In doing this you parse your string into a data structure, and can work with the separate keys and values,

If you simply want to remove the Device=<N> anywhere in the string, including at the end, you can use this replacement:

my $str = "Network=ABC,Network=10,Node=N360,Slot=3,Unit=R1,Group=RU,DeviceSet=1,Device=2";
$str =~ s/,Device=\d+//;
# result: "Network=ABC,Network=10,Node=N360,Slot=3,Unit=R1,Group=RU,DeviceSet=1"

Explanation:

  • search: ,Device=\d+
  • replace: (empty, e.g. remove the match)

This regex is more defensive. If however you'd like to remove the pattern only at the end, append a $ to the regex:

$str =~ s/,Device=\d+$//;

May be this will help

    if($str =~ m/(.*?)\,Device\b/){
       print "Out: $1";
    } else {
       print "Not matching";
    }

Here, (.*?) will find the first set string of Device word. Also, we need to set the boundary for the Word.

First, does you pattern actually match what you want? You want to find Device=<digit> at the end. That's not what your pattern does though. You don't include the information about the digit or the end of line. Anchors are important in these situations:

 /
 ,       # Start of final field to anchor this to a whole column
 Device
 =
 [0-9]
 $       # end of line
 /x

Second, the substitution operation tells you the number of substitutions it made. If it made a substitution, that's a line you want, so print the modified line:

if( $var =~ s/.../\n/ ) {
   print $var
   }
else {
   print "No match\n";
   }
Related