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

Hi all,

How would I go about reporting the position in a string of nested matches to a pattern like this

[XYZ]{3}[A-Za-z]{0,21}[ABC]{3}
Example:
FGTXYZGTFABCGHABC
would result with 3,3

or

FGTXYZADXYZGTYABC
would result with 3,8

I have been interating through the string one char at a time using a while loop, but this take quite a bit of time. Is there a faster way?
Thank you for your time.

edited: Mon Aug 18 20:06:42 2003 by jeffa - formatting

Replies are listed 'Best First'.
Re: nested pattern matching
by CombatSquirrel (Hermit) on Aug 18, 2003 at 19:14 UTC
    perl -e "'FGTXYZGTFABCGHABC' =~ /[XYZ]{3}([A-Za-z]{0,21})[ABC]{3}/; print $-[0] . ', ' . length($1);" __OUTPUT__ 3, 8
    Note that the output for your first example is 3, 8 instead of 3, 3. The appropiate RegEx for that would have been /[XYZ]{3}([A-Za-z]{0,21}?)[ABC]{3}/ (non-greedy quantifiers).
    Hope this helped.
      works great. Thanks. How would I put this into a while loop so I can traverse the whole string? Vince
        This should do the trick:
        #!perl use strict; use warnings; my $string = qq[FGTXYZGTFABCGHABCFGTXYZADXYZGTYABC]; while ($string =~ /[XYZ]{3}([A-Za-z]{0,21}?)[ABC]{3}/g) { print $-[0] . ', ' . length($1) . $/; } __OUTPUT__ 3, 3 20, 8
        got it. Just added the //g at the end. Vince
Re: nested pattern matching
by chromatic (Archbishop) on Aug 18, 2003 at 19:01 UTC

    I've never encountered such a problem, but could you use pos, capture the pattern, and use length on $1 to calculate what you need? You'd have to use the /g modifier, but I think it might work.