在 Rust 中,我可以过滤包含“1.2.3”或“1.2.3.4”等代码的字符串行吗?

问题描述 投票:0回答:1

我正在构建一个程序来帮助计算多个 PDF 中出现的不同代码的数量。我已经从 PDF 中获取了数据,这不是问题。我只需要根据行是否包含由句号分隔的 3 或 4 个数字的代码来过滤行。它们始终是 3 或 4 个数字,绝不会 >4 或 <3 numbers long. Below is my current attempt, but the filter I applied finds far too many false positives such as "AO3" and "08.5".

use pdf_extract::extract_text;
use std::ffi::OsStr;
use std::fs;
use std::path::PathBuf;

fn parse_pdf_data(pdf_path: &PathBuf) {
    let text: String = extract_text(pdf_path).unwrap();

    let decimal_lines: Vec<&str> = text
        .lines()
        .filter(|line: &&str| {
            line.to_string()
                .contains(['.', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'])
        })
        .collect();

    // maybe check length of each line is either 5 or 7?

    decimal_lines
        .iter()
        .for_each(|line: &&str| println!("{line}"));
}

fn main() {
    let pdfs: Vec<PathBuf> = fs::read_dir("DO_NOT_COMMIT")
        .unwrap()
        .map(|file: Result<fs::DirEntry, std::io::Error>| file.unwrap().path())
        .filter(|path: &PathBuf| path.extension() == Some(OsStr::new("pdf")))
        .collect();

    pdfs.iter().for_each(|pdf: &PathBuf| {
        println!("Parsing data from {:?}", pdf);
        parse_pdf_data(pdf);
    });
}

是否有更简单/更好的方法来执行此操作,而不是按这些字符进行过滤,然后检查 3 或 4 个带句号的数字的长度(长度为 5 或 7)?

rust filter substring pattern-matching
1个回答
0
投票

正则表达式是最简单的方法:

use regex::Regex; // 1.11.1

const TEXT: &str = "foobar
1
1.2
1.2.3
1.2.3.4
";

fn main() {
    let re = Regex::new (r"^[0-9]\.[0-9]\.[0-9](\.[0-9])?$").unwrap();
    let decimal_lines: Vec<&str> = TEXT
        .lines()
        .filter(|line| re.is_match (line))
        .collect();
    println!("{decimal_lines:?}")
}

游乐场

以上仅匹配单个数字(例如

1.2.3
但不匹配
12.34.56
)。如果要匹配多个数字,请将正则表达式替换为:
r"^[0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?$"

© www.soinside.com 2019 - 2024. All rights reserved.