Glob is rather simple compared to regular expressions, so there shouldn’t be a need to pull in a C library. Here’s a quick direct port of the algorithm from this post (my port is mostly untested, you’ll definitely want to check my work)
fn match(pattern: []const u8, name: []const u8) bool {
var pattern_i: usize = 0;
var name_i: usize = 0;
var next_pattern_i: usize = 0;
var next_name_i: usize = 0;
while (pattern_i < pattern.len or name_i < name.len) {
if (pattern_i < pattern.len) {
const c = pattern[pattern_i];
switch (c) {
'?' => { // single-character wildcard
if (name_i < name.len) {
pattern_i += 1;
name_i += 1;
continue;
}
},
'*' => { // zero-or-more-character wildcard
// Try to match at name_i.
// If that doesn't work out,
// restart at name_i+1 next.
next_pattern_i = pattern_i;
next_name_i = name_i + 1;
pattern_i += 1;
continue;
},
else => { // ordinary character
if (name_i < name.len and name[name_i] == c) {
pattern_i += 1;
name_i += 1;
continue;
}
},
}
}
// Mismatch. Maybe restart.
if (next_name_i > 0 and next_name_i <= name.len) {
pattern_i = next_pattern_i;
name_i = next_name_i;
continue;
}
return false;
}
// Matched all of pattern to all of name. Success.
return true;
}
You also may want to think about writing a custom std.fs.Dir.Walker implementation that does not recurse into subdirectories that are ignored by the glob if you care about that sort of thing.
Thank you so much for putting in the time and energy to help me
I was so used to having things handed to me in other languages (via their std library or community libraries) that I didn’t even consider solving the problem myself.
Thank you for making me realize my shortcomings.
I was looking for the same, and while learning zig (and bun internals), I ended doing:
1st relatively not too small zig project, it supports common patterns and ext-bash. Early version, I will add more options which can be found in other languages glob/match implementations.