MST

星途 面试题库

面试题:Rust正则表达式匹配与性能优化

有一个非常大的文本文件,里面包含大量的日志记录,每行日志记录形如"[时间戳] [日志级别] [日志内容]",例如"[2023 - 11 - 01 10:00:00] INFO Starting application"。现在需要在Rust程序中读取这个文件,并使用正则表达式匹配出所有日志级别为ERROR的记录。由于文件很大,性能是关键考量。请编写一个高效的Rust程序实现此功能,详细说明如何优化正则表达式的使用以避免性能瓶颈,包括但不限于预编译正则表达式、减少不必要的捕获组等措施。同时要处理文件读取过程中的错误情况。
30.0万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试
use std::fs::File;
use std::io::{self, BufRead};
use regex::Regex;

fn main() -> io::Result<()> {
    // 预编译正则表达式
    let re = Regex::new(r"\[(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\] ERROR (.*)").unwrap();

    let file = File::open("large_log_file.txt")?;
    let reader = io::BufReader::new(file);

    for line in reader.lines() {
        let line = line?;
        if let Some(caps) = re.captures(&line) {
            println!("时间戳: {},错误日志: {}", caps.get(1).unwrap().as_str(), caps.get(2).unwrap().as_str());
        }
    }

    Ok(())
}

优化说明

  1. 预编译正则表达式:在程序启动时使用Regex::new方法预编译正则表达式,这样在匹配每一行日志时就不需要重复编译,提高匹配效率。
  2. 减少不必要的捕获组:在正则表达式r"\[(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\] ERROR (.*)"中,只捕获时间戳和错误日志内容,去除不必要的捕获,从而减少内存开销。

错误处理

  1. 文件读取错误:使用File::open打开文件时返回io::Result<File>,通过?操作符将错误向上传播,如果文件打开失败,程序将返回错误信息。
  2. 正则表达式编译错误Regex::new返回Result<Regex, Error>,使用unwrap方法处理错误,如果正则表达式编译失败,程序将直接终止并打印错误信息。在实际应用中可以考虑更优雅的错误处理方式。
  3. 读取行错误reader.lines()返回的迭代器在读取每一行时也可能出错,通过?操作符处理这些错误,确保程序的健壮性。