spraff spraff - 6 months ago 28
Perl Question

Why do these impossible-looking regexes match these strings?

In Perl I have

if ($_ =~ /$search/)
print STDERR "$search matches $_";

which outputs

^[\s\t]*#?[\s\t]*unix_listener[\s\t\]+auth-userdb[\s\t]* matches unix_listener lmtp {
^[\s\t]*#?[\s\t]*unix_listener[\s\t\]+auth-userdb[\s\t]* matches unix_listener auth-userdb {
^[\s\t]*#?[\s\t]*unix_listener[\s\t\]+auth-userdb[\s\t]* matches #unix_listener /var/spool/postfix/private/auth {
^[\s\t]*#?[\s\t]*unix_listener[\s\t\]+auth-userdb[\s\t]* matches unix_listener dict {

This seems impossible since only one of the
strings contains

Even weirder, by adding a
to the end of the regex I get

^[\s\t]*#?[\s\t]*unix_listener[\s\t\]+auth-userdb[\s\t]*\{ matches unix_listener lmtp {

but no other matches (on the same input).

I thought I understood regexes of this type completely, but I can't figure out the logic here.

Someone please explain

  • why the first four
    lines match
    instead of only the one which contains

  • why adding the
    to the regex eliminated all but one match.


Look at the char class you wrote:

Start                 End
|                       |
v                       v
      Because this is escaped

So you effectively have


Replace whole regex with ^\s*#?\s*unix_listener\s+auth-userdb\s* since \t is included within \s.