Rust路径匹配库path-matchers的使用,高效处理文件路径匹配与模式解析
Rust路径匹配库path-matchers的使用,高效处理文件路径匹配与模式解析
特性
- 使用路径或glob表达式匹配路径
- 可以组合多个路径匹配器
使用方式
首先在Cargo.toml中添加依赖:
[dependencies]
path-matchers = "1.0"
然后就可以在代码中使用:
use std::path::PathBuf;
use path_matchers::{any, glob, PathMatcher, PathMatcherExt};
fn main() {
let path1 = PathBuf::from("images/big/best.png");
let path2 = PathBuf::from("images/small/32x32/best.jpg");
// 检查两个路径是否匹配 `images/**/best.*`
let all_best_images = glob("images/**/best.*").unwrap();
assert!(all_best_images.matches(&path1));
assert!(all_best_images.matches(&path2));
let all_jpgs = glob("images/**/*.jpg").unwrap();
assert!(!all_jpgs.matches(&path1));
assert!(all_jpgs.matches(&path2));
let all_pngs = glob("images/**/*.png").unwrap();
assert!(all_pngs.matches(&path1));
assert!(!all_pngs.matches(&path2));
// 现在我们可以组合两个匹配器来同时匹配jpg和png
let all_pics = all_jpgs.or(all_pngs);
assert!(all_pics.matches(&path1));
assert!(all_pics.matches(&path2));
// 也可以使用宏来实现同样的功能
let all_jpgs = glob("images/**/*.jpg").unwrap();
let all_pngs = glob("images/**/*.png").unwrap();
let all_pics = any!(all_jpgs, all_pngs);
assert!(all_pics.matches(&path1));
assert!(all_pics.matches(&path2));
}
完整示例代码
下面是一个更完整的示例,展示了path-matchers库的主要功能:
use std::path::PathBuf;
use path_matchers::{any, glob, PathMatcher, PathMatcherExt};
fn main() {
// 创建几个测试路径
let paths = vec![
PathBuf::from("src/main.rs"),
PathBuf::from("src/lib.rs"),
PathBuf::from("tests/test1.rs"),
PathBuf::from("docs/README.md"),
PathBuf::from("target/debug/build.rs"),
];
// 创建几个不同的匹配器
let rs_files = glob("**/*.rs").unwrap(); // 所有.rs文件
let test_files = glob("tests/**").unwrap(); // tests目录下的所有文件
let src_files = glob("src/*").unwrap(); // src目录下的直接文件
let markdown_files = glob("**/*.md").unwrap(); // 所有.md文件
// 组合匹配器
let source_files = rs_files.and(src_files); // src目录下的.rs文件
let test_or_docs = any!(test_files, markdown_files); // 测试文件或markdown文档
println!("文件匹配结果:");
for path in &paths {
println!(
"{}: source={}, test_or_docs={}",
path.display(),
source_files.matches(path),
test_or_docs.matches(path)
);
}
// 更复杂的组合示例
let build_artifacts = glob("target/**").unwrap(); // target目录下的所有文件
let interesting_files = any!(
source_files,
test_or_docs
).and_not(build_artifacts); // 源代码或文档,但不包括构建产物
println!("\n感兴趣的文件:");
for path in &paths {
if interesting_files.matches(path) {
println!("- {}", path.display());
}
}
}
这个示例展示了:
- 基本的glob模式匹配
- 使用
and
、or
和and_not
组合匹配器 - 使用
any!
宏简化组合逻辑 - 实际应用中的路径匹配场景
法律信息
该库采用双重许可:MIT
或UNLICENSE
。
1 回复
Rust路径匹配库path-matchers的使用指南
简介
path-matchers
是一个用于高效处理文件路径匹配与模式解析的Rust库。它提供了强大的路径匹配功能,支持通配符、正则表达式等多种匹配方式,特别适合需要处理文件系统路径匹配的场景。
主要特性
- 支持多种匹配模式:通配符、正则表达式、精确匹配等
- 高效性能:优化的匹配算法,适合处理大量路径
- 易于使用的API
- 支持自定义匹配器
安装
在Cargo.toml
中添加依赖:
[dependencies]
path-matchers = "0.3"
基本使用方法
1. 通配符匹配
use path_matchers::{any, any_with, Pattern};
fn main() {
// 创建匹配器
let matcher = Pattern::new("src/**/*.rs").unwrap();
// 测试路径是否匹配
assert!(matcher.matches("src/lib.rs"));
assert!(matcher.matches("src/foo/bar.rs"));
assert!(!matcher.matches("src/foo/bar.txt"));
}
2. 正则表达式匹配
use path_matchers::RegexMatcher;
fn main() {
let matcher = RegexMatcher::new(r"^src/.*\.(rs|toml)$").unwrap();
assert!(matcher.matches("src/lib.rs"));
assert!(matcher.matches("src/Cargo.toml"));
assert!(!matcher.matches("src/foo.txt"));
}
3. 组合匹配器
use path_matchers::{any, all, Pattern};
fn main() {
let rs_files = Pattern::new("**/*.rs").unwrap();
let exclude_tests = Pattern::new("!**/tests/**").unwrap();
let matcher = all![rs_files, exclude_tests];
assert!(matcher.matches("src/lib.rs"));
assert!(!matcher.matches("src/tests/test.rs"));
}
4. 自定义匹配函数
use path_matchers::Matcher;
fn main() {
let matcher = Matcher::new(|path: &str| path.len() > 10);
assert!(matcher.matches("a/very/long/path"));
assert!(!matcher.matches("short"));
}
高级用法
1. 从多个模式创建匹配器
use path_matchers::Pattern;
fn main() {
let patterns = vec![
"src/**/*.rs",
"tests/**/*.rs",
"!**/temp/**"
];
let matcher = Pattern::new_set(patterns).unwrap();
assert!(matcher.matches("src/lib.rs"));
assert!(matcher.matches("tests/test.rs"));
assert!(!matcher.matches("src/temp/mod.rs"));
}
2. 遍历目录并匹配文件
use path_matchers::Pattern;
use std::path::Path;
use walkdir::WalkDir;
fn find_matching_files(dir: &str, pattern: &str) -> Vec<String> {
let matcher = Pattern::new(pattern).unwrap();
let mut matches = Vec::new();
for entry in WalkDir::new(dir) {
let entry = entry.unwrap();
let path = entry.path().to_string_lossy();
if matcher.matches(&path) {
matches.push(path.into_owned());
}
}
matches
}
fn main() {
let matches = find_matching_files(".", "**/*.rs");
println!("Found Rust files: {:?}", matches);
}
性能提示
- 对于重复使用的模式,尽量重用
Matcher
实例 - 对于复杂匹配,考虑使用
RegexMatcher
而不是多层嵌套的通配符 - 在遍历大量文件时,先创建匹配器再遍历,而不是每次检查都新建匹配器
完整示例
以下是一个结合了多种匹配方式的完整示例:
use path_matchers::{Pattern, RegexMatcher, Matcher, all};
use walkdir::WalkDir;
fn main() {
// 1. 通配符匹配示例
let pattern_match = Pattern::new("src/**/*.rs").unwrap();
println!("src/main.rs matches: {}", pattern_match.matches("src/main.rs"));
println!("src/foo/bar.rs matches: {}", pattern_match.matches("src/foo/bar.rs"));
println!("src/foo.txt matches: {}", pattern_match.matches("src/foo.txt"));
// 2. 正则表达式匹配示例
let regex_match = RegexMatcher::new(r"^data/.*\.(csv|json)$").unwrap();
println!("data/test.csv matches: {}", regex_match.matches("data/test.csv"));
println!("data/config.json matches: {}", regex_match.matches("data/config.json"));
println!("data/notes.txt matches: {}", regex_match.matches("data/notes.txt"));
// 3. 组合匹配器示例
let include_pattern = Pattern::new("**/*.rs").unwrap();
let exclude_pattern = Pattern::new("!**/test/**").unwrap();
let combined_matcher = all![include_pattern, exclude_pattern];
println!("src/lib.rs matches: {}", combined_matcher.matches("src/lib.rs"));
println!("src/test/mod.rs matches: {}", combined_matcher.matches("src/test/mod.rs"));
// 4. 自定义匹配函数示例
let custom_matcher = Matcher::new(|path: &str| {
path.contains("important") && path.ends_with(".txt")
});
println!("docs/important.txt matches: {}", custom_matcher.matches("docs/important.txt"));
println!("docs/notes.txt matches: {}", custom_matcher.matches("docs/notes.txt"));
// 5. 实际应用:遍历目录查找匹配文件
let target_dir = ".";
let search_pattern = "**/*.rs";
println!("\nSearching for {} files in {}:", search_pattern, target_dir);
let matcher = Pattern::new(search_pattern).unwrap();
for entry in WalkDir::new(target_dir) {
let entry = entry.unwrap();
let path = entry.path().to_string_lossy();
if matcher.matches(&path) {
println!("Found: {}", path);
}
}
}
总结
path-matchers
库提供了灵活高效的路径匹配功能,适用于文件处理、构建系统、代码分析等多种场景。通过组合不同的匹配器和模式,可以实现复杂的路径匹配逻辑。