Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Pattern matching: backslash escaping not active in pattern passed from variable



Peter Stephenson's patch for case pattern matching applied cleanly
against the latest git code and is working perfectly. Many thanks.

There is another snag I've found in pattern matching, which seems to
have survived this patch: backslash escaping does not seem match the
standard if a glob pattern is passed from a variable or parameter. The
standard says:

http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_13_01
> A <backslash> character shall escape the following character. The
> escaping <backslash> shall be discarded.

This works correctly with a literal pattern:

case abc in ( a\bc ) echo yes ;; ( * ) echo no ;; esac
Got expected output: yes

But it does *not* work correctly if the pattern is in a variable or
parameter:

glob='a\bc'
case abc in ( $glob ) echo yes ;; ( * ) echo no ;; esac
Expected output: yes (produced by bash, ksh93, dash)
Got output: no (produced by zsh, mksh, ash)

To be fair, existing implementations seem wildly inconsistent here, so
perhaps I'm misreading something. In any case, the inconsistency is
unfortunate. I like to use this simple function so I can write something
like: if match "$somestuff" '*stuff*'; then [...]

match() {
        case "$1" in ( $2 ) return 0 ;; esac
        return 1
}

But the inconsistent handling of backslash escaping in glob patterns
passed from variables or parameters makes it impossible to portably
match a literal '*' or '?' using a method like this. mksh and ash never
match a literal escaped \* and \?; oddly enough, zsh does, but does not
match a (redundantly) escaped alphanumeric character.

In any case, I would expect backslash escaping to work the same way
whether the glob pattern is passed from a variable or parameter or not.

Thanks,

- Martijn



Messages sorted by: Reverse Date, Date, Thread, Author