#glob-pattern #pattern-matching #glob #pattern #walkdir

fast-glob

A high-performance glob matching crate for Rust

11 unstable releases (3 breaking)

0.4.5 Feb 27, 2025
0.4.4 Feb 23, 2025
0.4.3 Dec 27, 2024
0.4.0 Aug 20, 2024
0.1.0 May 27, 2024

#79 in Filesystem

Download history 1967/week @ 2024-11-19 1462/week @ 2024-11-26 1308/week @ 2024-12-03 2064/week @ 2024-12-10 1708/week @ 2024-12-17 2208/week @ 2024-12-24 1987/week @ 2024-12-31 2711/week @ 2025-01-07 3024/week @ 2025-01-14 2546/week @ 2025-01-21 2072/week @ 2025-01-28 2142/week @ 2025-02-04 3149/week @ 2025-02-11 4297/week @ 2025-02-18 4695/week @ 2025-02-25 3643/week @ 2025-03-04

16,180 downloads per month
Used in 26 crates (5 directly)

MIT license

22KB
318 lines

fast-glob

Introduce

A high-performance glob matching crate for Rust based on devongovett/glob-match.

Key Features:

  • Up to 60% performance improvement.
  • Supports more complete and well-rounded features.

Examples

use fast_glob::glob_match;

let glob = "some/**/n*d[k-m]e?txt";
let path = "some/a/bigger/path/to/the/crazy/needle.txt";

assert!(glob_match(glob, path));

Syntax

Syntax Meaning
? Matches any single character.
* Matches zero or more characters, except for path separators (e.g. /).
** Matches zero or more characters, including path separators. Must match a complete path segment (i.e. followed by a / or the end of the pattern).
[ab] Matches one of the characters contained in the brackets. Character ranges, e.g. [a-z] are also supported. Use [!ab] or [^ab] to match any character except those contained in the brackets.
{a,b} Matches one of the patterns contained in the braces. Any of the wildcard characters can be used in the sub-patterns. Braces may be nested up to 10 levels deep.
! When at the start of the glob, this negates the result. Multiple ! characters negate the glob multiple times.
\ A backslash character may be used to escape any of the above special characters.

Benchmark

Test Case 1

const GLOB: &'static str = "some/**/n*d[k-m]e?txt";
const PATH: &'static str = "some/a/bigger/path/to/the/crazy/needle.txt";
mine                       time:   [87.185 ns 87.307 ns 87.440 ns]
glob                       time:   [376.83 ns 377.42 ns 378.09 ns]
globset                    time:   [21.027 µs 21.035 µs 21.045 µs]
glob_match                 time:   [203.66 ns 203.87 ns 204.09 ns]
glob_pre_compiled          time:   [63.569 ns 63.684 ns 63.800 ns]
globset_pre_compiled       time:   [91.543 ns 91.591 ns 91.651 ns]

Test Case 2

const GLOB: &'static str = "some/**/{tob,crazy}/?*.{png,txt}";
const PATH: &'static str = "some/a/bigger/path/to/the/crazy/needle.txt";
mine                       time:   [198.63 ns 199.26 ns 200.08 ns]
globset                    time:   [41.489 µs 41.575 µs 41.681 µs]
glob_match                 time:   [367.32 ns 368.10 ns 368.77 ns]
globset_pre_compiled       time:   [91.498 ns 91.648 ns 91.883 ns]

FAQ

Why not use the more efficient glob_match for brace expansion?

glob_match is unable to handle complex brace expansions. Below are some failed examples:

  • glob_match("{a/b,a/b/c}/c", "a/b/c")
  • glob_match("**/foo{bar,b*z}", "foobuzz")
  • glob_match("**/{a,b}/c.png", "some/a/b/c.png")

Due to these limitations, brace expansion requires a different implementation that can handle the complexity of such patterns, resulting in some performance trade-offs.

Credits

Dependencies

~68KB