On 5/21/10 Fri  May 21, 2010  12:13 PM, "Akhthar Parvez K"
<[email protected]> scribbled:

> On Friday 21 May 2010, Jim Gibson wrote:

>> You are getting undefs because you
>> have alternation (|) between two

>> sub-patterns and capturing parentheses in
>> each sub-pattern. You also have

>> nested parentheses, with a capturing
>> parenthese pair around the whole.

>>

>> Your regular expression is this:


>>   
>>   /(little(\D*wonder)|high(.*like))/

>>

>> with 3 sets of parentheses. Perl is returning what matched by each set of ()

>> for each match. You have 3 sets of () and 3 matches. Therefore you are

>> getting 9 returned values. Because you have alternation, only sub-pattern is

>> matching, and the pair of () in the non-matched sub-pattern is returning
>> undef.




> Shouldn't 
> Perl be smart enough to understand that the outer most pair of paranthesis and
> | symbol were solely used for alternation (since there're nothing within the
> outermost paranthesis except another set of paranthesis and alternation) and
> it doesn't need to pick something out of it.

In general, Perl (nor any other language) will try to figure out what you
want and give you just that. Other people will want different things. You
need to tell Perl exactly what you want using Perl syntax. For regular
expressions, this means returning a value for each set of () in your regex.

If you don't want the outer set of parentheses to capture, then use
non-capturing parentheses:  (?:  ). See 'perldoc perlre' and search for
"Extended Patterns".

>> If you really want to use regular expression, consider using look-ahead

>> tests and a while loop and don't expect to get everything you need in a

>> single pass through your string.



> I've earlier been using a for loop to get both the matched part and
> the critical part. However, I thought it would be better if I can avoid the
> loop as that would cause an unwanted delay if there are more strings to be
> matched, so I thought to get it done in a single statement, or a group of
> statements, without any loop.

Perl loops are very fast and will not introduce any noticeable delays in
your program. Regular expressions can be slow in some applications,
particularly if they contain lots of wild-cards and you are using them on
long strings. In either case, you are not likely to notice a difference. If
you are noticing a delay, then there is some other explanation than the use
of a for loop. If you do not have a delay problem but are just looking for
more speed, then you need to benchmark your program to see where it is
spending the most time.

Note that a while loop is more appropriate than a for loop for iterating
over the matches in a regex with the /g modifier. Something link (untested):

    while( m{ (?:  a+(b+) | c+(d+) )}xg ) {
      if( $1 ) {
        # a+(b+) was matched, $1 contains b+
      }else{
        # c+(d+) was matched, $2 contains d+
      }
    }




--
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
http://learn.perl.org/


Reply via email to