http://www.perlmonks.org?node_id=11137512

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

Hi

I have this assignment

When a string comes with below content

01/LC-13/E10GbE-1,01/LC-14/E10GbE-1

It must take numbers 13, 1, 14 and 1, in order as indicated

And with this instruction is achieved

perl -le '@m = ( "01/LC-13/E10GbE-1,01/LC-14/E10GbE-1" =~ /./\w+-(\d+) +/\w+-(\d+)(?=,./\w+-(\d+)/\w+-(\d+))/); print for @m'

But when string comes with

01/LC-13/E10GbE-1

It must take numbers 13 and 1

And when I run my example does not work

$ perl -le '@m = ( "01/LC-13/E10GbE-1" =~ /./\w+-(\d+)/\w+-(\d+)(?=,./ +\w+-(\d+)/\w+-(\d+))/); print for @m'

It does not return anything

Which seems to be the trouble?

I don't know much about regular expressions

Regards.

Replies are listed 'Best First'.
Re: Problem with regexp to match
by choroba (Cardinal) on Oct 14, 2021 at 15:23 UTC
    In fact, you're interested in digits after a minus. Use the global matching to get all the matches:

    #!/usr/bin/perl use warnings; use strict; use feature qw{ say }; for my $string ('01/LC-13/E10GbE-1,01/LC-14/E10GbE-1', '01/LC-13/E10GbE-1' ) { my @numbers = $string =~ /-([0-9]+)/g; say "@numbers"; }
    map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
Re: Problem with regexp to match
by LanX (Saint) on Oct 14, 2021 at 15:31 UTC
    One of the obvious problems is, that you want to use slashes inside your regex without escaping them.

    / --> \/

    If I where you I'd change delimiter and try m{REGEX} instead of m/REGEX/ .

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

    update

    there where more issues, but this works for me ( perl -dE0 starts the debugger )

    DB<25> @m = qw{01/LC-13/E10GbE-1 01/LC-13/E10GbE-1,01/LC-14/E10GbE- +1} DB<26> say join ":", m{\d\d/\w+-(\d+)/\w+-(\d+),?}g for @m 13:1 13:1:14:1 DB<27>

    update

    If the snippets don't always start with \d\d change it to \d+

    If I where you I'd consider spliting on , and then / .

    Then applying a simple regex, should be more stable and maintainable.

      If I where you I'd change delimiter and try m{REGEX} instead of m/REGEX/

      Completely agree.
      When it was first recommended to me that I make this change, I thought it wouldn't make much difference. In fact it has had a significant effect on the legibility and maintainability of my code.

      One of the many fabulous suggestions from the Monastery.

Re: Problem with regexp to match
by AnomalousMonk (Archbishop) on Oct 14, 2021 at 22:25 UTC

    When matching patterns with regexes, the first task is to figure out what the pattern is that you want to match. From the examples you've given us, it seems as if the pattern is

    ++--------+-------++--------+---- one or more digits || | || | VV V VV V 1/LC-13/E10GbE-1,01/LC-14/E10GbE-1 A A A A | | | | +---------+-------+---------+---- if preceded by hyphen/dash ++--------+---- one or more digits || | VV V 1/LC-13/E10GbE-1 A A | | +---------+---- if preceded by hyphen/dash

    This solution is a variation on that of choroba given here. It introduces the idea of the lookaround assertion (the (?<= -) expression) and uses the fact that the /g modifier operating in list context allows return of the entire match without using capturing parentheses.

    Win8 Strawberry 5.8.9.5 (32) Thu 10/14/2021 17:41:51 C:\@Work\Perl\monks >perl -Mstrict -Mwarnings for my $str ( '01/LC-13/E10GbE-1,01/LC-14/E10GbE-1', '01/LC-13/E10GbE-1', ) { my @m = $str =~ m{ (?<= -) \d+ }xmsg; print "'$str' ->"; print " '$_'" for @m; print "\n"; } ^Z '01/LC-13/E10GbE-1,01/LC-14/E10GbE-1' -> '13' '1' '14' '1' '01/LC-13/E10GbE-1' -> '13' '1'
    Please see perlre, perlretut, perlreref and perlrequick.


    Give a man a fish:  <%-{-{-{-<

Re: Problem with regexp to match
by FeistyLemur (Acolyte) on Oct 14, 2021 at 18:38 UTC

    I use this website https://regex101.com/ for live testing any regex I want to use. I find it quick and handy and it's informative for those who are not that well versed in it yet as well.

      > I use this website https://regex101.com/ for live testing any regex I want to use.

      It's certainly nice and well made, thanks! :)

      But please be aware that it doesn't offer Perl Regexes only PCRE.

      And PCRE has - despite the name - some incompatibilities.

      I don't know about PCRE2 tho... but expect it to keep compatibility to PCRE1.

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

        It's similar enough that you get the gist of what what you're capturing, plus teach you the basics of regex. The only thing you really have to remember to do is escape your characters properly for perl.

Re: Problem with regexp to match
by logangha (Acolyte) on Oct 14, 2021 at 17:19 UTC

    Thanks for the tips

    I will follow some considerations in order to achieve this matter

    Regards