in reply to Re: Multiple matches of a regex
in thread Multiple matches of a regex

Thanks for the tip, Fletch! (Can't ++ you today, ran out of votes... Wait for monday please!) So that leaves me with:

use strict; my $regex = qr/(\d\d):(\d\d)(?::(\d\d))?/; # 01234567890123456 my $string = "11:30 or 11:29:53"; my $res; while ($string =~ /$regex/g) { my $pos = $-[0]; my ($ind, @match); for $ind (1..$#-) { push @match, substr ($string, $-[$ind], $+[$ind] - $-[$ind]); } $res->{$pos} = \@match; } use Data::Dumper; print Data::Dumper::Dumper $res;
This prints:
$VAR1 = { '0' => [ '11', '30' ], '9' => [ '11', '29', '53' ] };
as it should.

What I don't like about this solution is that it involves a lot of substr calls to get strings that are stored in the $n variables anyway. Is there a better way to do this?

Thanks,

pike

Replies are listed 'Best First'.
Re: Re: Re: Multiple matches of a regex
by BrowserUk (Patriarch) on Jan 10, 2003 at 19:09 UTC

    As you are using capturing brackets within your regex, your required substrings are already being placed into the variables $1 $2 $3, so there is no need to use substr to isolate the substrings a second time. The only tricky bit is that $3 may have no value, so I've used grep to exclude it if it has no value.

    #! perl -slw use strict; use Data::Dumper; my $regex = qr/(\d\d):(\d\d)(?::(\d\d))?/; # 01234567890123456 my $string = "11:30 or 11:29:53"; my $res; $res->{$-[0]} = [grep $_, $1, $2, $3] while $string =~ /$regex/g; print Dumper $res; __END__ c:\test>225814 $VAR1 = { '0' => [ '11', '30' ], '9' => [ '11', '29', '53' ] }; c:\test>

    Examine what is said, not who speaks.

    The 7th Rule of perl club is -- pearl clubs are easily damaged. Use a diamond club instead.

Re: Re: Re: Multiple matches of a regex
by ihb (Deacon) on Jan 10, 2003 at 19:09 UTC
    If you have anything against substr calls you can do this symbolically (through more people will probably have something against this than repeated substr calls).
    no strict 'refs'; my @groups = map $$_, 1 .. $#+;
    If I shall be picky, in your question you wanted the first match to return   ['11', '30', undef] while in your reply you said   ['11', '30'] is what you want. As I pointed out here you should consider the difference between $#+ and $#-. Also, unmatched groups would be '' with your code. Perhaps that's what you want, but it won't be fully analogous to using the $<DIGITS> variables. If done symbolically it sure will be analogous though, since you actually use the $<DIGITS> variables.

    Hope I've helped,
    ihb