fnmatch-regex 0.2.0

Convert a glob-style pattern to a regular expression.
Documentation
# fnmatch-regex - build regular expressions to match glob-style patterns

This crate currently provides a single function, `glob_to_regex`, that
converts a glob-style pattern with some shell extensions to a regular
expression. Note that it only handles text pattern matching, there are
no attempts to verify or construct any filesystem paths.

The glob-style pattern features currently supported are:

- any character except `?`, `*`, `[`, `\`, or `{` is matched literally

- `?` matches any single character except a slash (`/`)

- `*` matches any sequence of zero or more characters that does not
  contain a slash (`/`)

- a backslash allows the next character to be matched literally, except
  for the `\a`, `\b`, `\e`, `\n`, `\r`, and `\v` sequences

- a `[...]` character class supports ranges, negation if the very first
  character is `!`, backslash-escaping, and also matching
  a `]` character if it is the very first character possibly after
  the `!` one (e.g. `[]]` would only match a single `]` character)

- an `{a,bbb,cc}` alternation supports backslash-escaping, but not
  nested alternations or character classes yet

Note that the `*` and `?` wildcard patterns, as well as the character
classes, will never match a slash.

Examples:

- `abc.txt` would only match `abc.txt`

- `foo/test?.txt` would match e.g. `foo/test1.txt` or `foo/test".txt`,
  but not `foo/test/.txt`

- `/etc/c[--9].conf` would match e.g. `/etc/c-.conf`, `/etc/c..conf`,
   or `/etc/7.conf`, but not `/etc/c/.conf`

- `linux-[0-9]*-{generic,aws}` would match `linux-5.2.27b1-generic`
  and `linux-4.0.12-aws`, but not `linux-unsigned-5.2.27b1-generic`

Note that the negation modifier for character classes is `!`, not `^`. 

    let re_name = fnmatch_regex::glob_to_regex("linux-[0-9]*-{generic,aws}")?;
    for name in &[
        "linux-5.2.27b1-generic",
        "linux-4.0.12-aws",
        "linux-unsigned-5.2.27b1-generic"
    ] {
        let okay = re_name.is_match(name);
        println!(
            "{}: {}",
            name,
            match okay { true => "yes", false => "no" },
        );
        assert!(okay == !name.contains("unsigned"));
    }