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());
        }
    }
}

这个示例展示了:

  1. 基本的glob模式匹配
  2. 使用andorand_not组合匹配器
  3. 使用any!宏简化组合逻辑
  4. 实际应用中的路径匹配场景

法律信息

该库采用双重许可:MITUNLICENSE


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);
}

性能提示

  1. 对于重复使用的模式,尽量重用Matcher实例
  2. 对于复杂匹配,考虑使用RegexMatcher而不是多层嵌套的通配符
  3. 在遍历大量文件时,先创建匹配器再遍历,而不是每次检查都新建匹配器

完整示例

以下是一个结合了多种匹配方式的完整示例:

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库提供了灵活高效的路径匹配功能,适用于文件处理、构建系统、代码分析等多种场景。通过组合不同的匹配器和模式,可以实现复杂的路径匹配逻辑。

回到顶部