user690182
user690182

Reputation: 279

Network interface matching

What I am trying to do is given a string like :

"hello GigabitEthernet1/13 mplampla"

to extract the interface, for example:

"GigabitEthernet1/13"

and to extract the first 2 characters and then the interface number, for example:

"Gi1/13"

What I am doing wrong ?

#!/usr/bin/perl     -w

use     strict ;
use     warnings ;

my $string = "hello GigabitEthernet1/13 mplampla" ;
$string =~ /(^[a-z]{2}*[0-9]\/*[0-9]*\/*[0-9]*)/ ;
print $string."\n" ;

PS. the interface number can be like "Po4", "TenGigabitEthernet2/0/0.13", etc.

Upvotes: 0

Views: 2365

Answers (3)

MisterEd
MisterEd

Reputation: 1735

Use capture groups:

$string =~ s|
        ^.*            # match beginning text (to be replaced)
        \b(\w{2})\w+   # capture the first two letters (in $1)
        (
          (?: \d+/? )+ # and one or more digits followed by 0 or 1 slashes,
                       # one or more times (in $2)
        )
        .*$            # match ending text (to be replaced)

    |$1$2|x;  # replace with only the contents of the capture groups

Upvotes: 1

Birei
Birei

Reputation: 36282

One way:

use     strict ;
use     warnings ;

my $string = "hello GigabitEthernet1/13 mplampla" ;
my @result = $string =~ /\s(\w{2})(?:\D*)(\d+\S*)/;
{
    local $" = qq[];
    print qq[@result\n];
}

The regex:

\s                        # A space character.
(\w{2})                   # Two alphabetic characters. Save as group 1.
(?:\D*)                   # Any no-numeric characters. No save them.
(\d+\S*)                  # From first digit found until a space. Save as group 2.

For printing:

$"                  # It is the separator for array elements. It is set to a blank.
@result             # It is an array with grouped elements of the regular expression.

Upvotes: 2

ean5533
ean5533

Reputation: 8994

There are several things wrong with your regex -- let's tackle them one by one.

  1. The ^ character, when used outside of square brackets, means "the beginning of the line". So you've told the regex engine that the thing you're looking for is at the very beginning of the input string, which isn't true. So take that ^ out.
  2. By using [a-z] you've specifically told the engine only to look for lowercase letters. You can either change it to [A-Za-z] or add an i after the last slash to make the regex case-insensitive.
  3. That first * you have doesn't make sense where it is -- I think what you meant to do is put something like this in its place: [a-z]* (which means 0 or more letters).

So applying all those changes, here is your new regex:

/([a-z]{2}[a-z]*[0-9]\/*[0-9]*\/*[0-9]*)/i

That regex will capture GigabitEthernet1/13.

Edit: Here is a place you can play around with your regex and see how it responds to changes:

http://rubular.com/r/lsucbd8E4J

Upvotes: 1

Related Questions