Re: Re[4]: Pattern Regular Expressions: Consecutive ORs not handled corr ectl y

"Daniel F. Savarese" <[email protected]> Fri, 06 May 2005 15:16:54 -0400
Newsgroups gmane.comp.jakarta.oro.user
Message-ID <[email protected]>
In message <[email protected]>, Sergey Samokhodkin writes:
>That's what I mean:
>$str =~ /^foo$/  - check for exact match, analog to matches()
>$str =~ /foo/  - check for partial match, analog to contains()
...
>What I don't understand is, why the 'regexp("foo").matches(str)' is
>diffrent in behaviour from the 'regexp("^(?:foo)$").contains(str)'.
>IMHO these are the same and should behave the same.

The heart of the matter seems to be a difference in expectations.  I
understand why you could expect matches() to behave that way.  However,
its documentation explains that it's not the same as ^pattern$.  I'll
try to explain why.  Forgive me if I don't do the best job.

matches() tests whether or not a pattern matches the input it is given.
This means that the matching process must start at the beginning of
the input and stop at the end of the input.  If the matching process stops
before the end of the input, then there's no match.  The method answers
the question "Is this input character sequence a member of the set of all
the character sequences matched by this pattern?"

It may make more sense thinking about it this way.  matches() returns true
if and only if S =~ m/(P)/ is true and $1 equals S.  For example:

  sub matches(@) {
    my ($pat, $str) = @_;
    $str =~ m/($pat)/;
    return ($str eq $1);
  }

  printf "%d\n%d\n", matches("foo|foot", "foo"), matches("foo|foot", "foot");

In my opinion, the important thing is for the behavior to be documented.
If it's not sufficiently clear, then we ought to make it more clear.
Documentation patches are welcome.

Now, one can argue that we should add a validate() method specifically
for input validation with the behavior you expected.  My opinion
is that belongs in a higher level class built on top of the matcher.
However, in the past it has been suggested that support be added
to know how much of a failed match was matched.  For example, if
you want to do progressive input validation (e.g., make sure an IP
address is being entered).  Then you'd want to know that even though
123 isn't matched by \d{1,3}(?:\.\d{1,3}){3}, that at
least something acceptable is in the process of being entered (e.g.,
you'd reject ABC as it was being entered).  That's something that
would require support inside of the matcher (perhaps a prefixMatches
method?), but wouldn't be hard to add.  I know I'm going off topic
at this point, but if there's more stuff you want the software to do,
please submit a patch or at least file an enhancement issue report
through bugzilla.

daniel