» Rust创建命令行程序grep » 2. 开发 » 2.2 初始版本

初始版本

src/lib.rs:

use std::fs::File;
use std::io::{self, BufRead};

use regex::Regex;

pub fn grep(pattern: &str, file_path: &str) -> io::Result<Vec<String>> {
    let regex = match Regex::new(pattern) {
        Ok(r) => r,
        Err(err) => return Err(io::Error::new(io::ErrorKind::InvalidInput, err)),
    };

    let file = File::open(file_path)?;
    let reader = io::BufReader::new(file);

    let mut matched_lines = Vec::new();
    for (_, line) in reader.lines().enumerate() {
        let line = line?;
        if regex.is_match(&line) {
            matched_lines.push(line.trim().to_string());
        }
    }
    Ok(matched_lines)
}

regex 包提供正则表达式功能,其是用于文本模式匹配的强大工具。

因为 Rust 标准库没有原生携带正则表达式,所以你需要将其添加为项目依赖。

Cargo.toml:

[package]
name = "lr_grustep"
version = "0.1.0"
edition = "2021"

# 查看更多配置项信息: https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
regex = "1.5"

此处,regex 是“包”名,1.5 是想要的版本号。你可以依据自身需求使用不同版本号。

main.rs:

use std::env;

use lr_grustep::grep;

fn main() {
    let args: Vec<String> = env::args().collect();

    if args.len() < 3 {
        eprintln!("Usage: {} <pattern> <file_path>", args[0]);
        std::process::exit(1);
    }

    let pattern = &args[1];
    let file_path = &args[2];

    match grep(pattern, file_path) {
        Ok(matched_lines) => {
            for line in matched_lines {
                println!("{}", line);
            }
        }
        Err(err) => {
            eprintln!("Error: {}", err);
        }
    }
}

std::env::args 函数可方便地解析命令行参数。

尝试运行:

# 在文件 main.rs 中查找“line”
cargo run line src/main.rs

得到如下结果:

    Finished dev [unoptimized + debuginfo] target(s) in 0.02s
     Running `target/debug/lr_grustep line src/main.rs`
Ok(matched_lines) => {
for line in matched_lines {
println!("{}", line);

注意:忽略前两行来自 cargo 的调试信息。