初始版本
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
的调试信息。