ڼС
梦回起点
做你害怕做的事,你会发现:不过如此
本站基于WordPress—主题by 设计窝
冀ICP备15003737号
梦回起点
Copyright © 2015-2024 All rights reserved.

rust支持正则表达式的判断路径是否存在

因为需要判断一个特定的路径是否存在,但是该路径中存在一个版本号,不确定是什么,所以就自己实现了一个函数

use std::fs;
use std::path::{Path, PathBuf};
use regex::Regex;
use pelite::pe64::{Pe, PeFile};
use pelite::resources::version_info::VersionInfo;
use std::error::Error;
use std::fs::File;
use std::io::Read;

fn path_exists_regex(path_pattern: &str) -> Result<bool, Box<dyn std::error::Error>> {
    let path_parts: Vec<&str> = path_pattern.split(std::path::MAIN_SEPARATOR).collect();
    if 0 == path_parts.len() {
        return  Ok(false);
    }
    let part_zero = String::from(path_parts[0]);
    if part_zero.find(":").is_none(){
        directory_exists_regex(&Path::new("."), &path_parts, 0)
    }else{
        directory_exists_regex(&Path::new(if !path_parts[0].is_empty() {path_parts[0]}else{"/"}), &path_parts, 1)
    }
}

fn directory_exists_regex(current_path: &Path, path_parts: &[&str], depth: usize) -> Result<bool, Box<dyn std::error::Error>> {

    let mut new_path = String::from(current_path.to_str().unwrap());
    if !new_path.ends_with(std::path::MAIN_SEPARATOR)
    {
        new_path.push(std::path::MAIN_SEPARATOR);
    }

    let current_path = Path::new(&new_path);

    if depth == path_parts.len() {
        // 如果已经匹配了所有部分,说明找到了完全匹配的路径
        return Ok(true);
    }

    // 正则匹配,如果是windows平台,那么忽略大小写
    let reg = format!("{}{}", if cfg!(target_os = "windows"){"(?i)"}else{""}, path_parts[depth]);
    let re = Regex::new(reg.as_ref())?;
    let search_path = if current_path.as_os_str().is_empty() {
        Path::new(".")
    } else {
        current_path
    };

    let res = fs::read_dir(search_path);
    if res.is_ok(){
        let res = res.unwrap();
        for entry in res {
            if entry.is_err(){
                continue;
            }

            let entry = entry?;
            let path = entry.file_name();

            let path = path.to_string_lossy().to_owned();

            if re.is_match(&path) {

                let path = Path::new(path.as_ref());
                let new_path = current_path.join(path);

                // 如果这是最后一部分,那么直接返回TRUE
                if depth == path_parts.len() - 1 {
                    return Ok(true);
                }

                // 递归搜索下一级
                if new_path.is_dir() {
                    if directory_exists_regex(&new_path, path_parts, depth + 1)? {
                        return Ok(true);
                    }
                }
            }
        }
    }
    Ok(false)
}

pub fn existsex(path : &str)->bool{
    //这个支持正则表达式
    match path_exists_regex(path) {
        Ok(exists) =>exists,
        Err(_) => false,
    }
}
#[test]
fn test_exists_regex()
{
    assert!(true == existsex(r#"C:\.*\System.*"#));
    assert!(true == existsex(r#"C:\Windows\appcompat\appraiser\APp.*"#));
    assert!(true == existsex(r#"C:\Windows\appcompat\appraiser\t.*"#));
    assert!(false == existsex(r#"C:\Windows\appcompat\appraiser\f.*"#));
    assert!(false == existsex(r#"C:\Windows\appcompat\appr[a-z]{2,3}er\f.*"#));
    assert!(true == existsex(r#"C:\Windows\appcompat\appr[a-z]{2,4}er\a.*"#));
    assert!(false == existsex(r#"123"#));
    assert!(true == existsex(r#"c.*"#));
}
2022-11-18
                         
暂无评论

发表回复