Hasunohana
Hasunohana

Reputation: 615

Using Regex inside for loop

I'm learning Rust and trying to apply a regex inside for loop reading a line.

extern crate regex;
use regex::Regex;

use std::fs::File;
use std::io::{BufReader, Result, BufRead};

fn main() -> Result<()> { 
    let file = File::open("logs.log")?;
    let reader = BufReader::new(file);
    
    let re = Regex::new(r"^\w{3}\s{1,2}\d{1,2}\s(?:\d{2}:){2}\d{2}").unwrap();

    for line in reader.lines() {
        println!("{}", re.is_match(line));
    }

    Ok(())
} 

using cargo run I receive the error above

  --> src/main.rs:14:36
   |
14 |         println!("{}", re.is_match(line));
   |                                    ^^^^ expected `&str`, found enum `std::result::Result`
   |
   = note: expected reference `&str`
                   found enum `std::result::Result<String, std::io::Error>`

using rustc file.rs, receive this

| extern crate regex;
  | ^^^^^^^^^^^^^^^^^^^ can't find crate

is that the right way to applying regex ?

Upvotes: 2

Views: 471

Answers (3)

Aplet123
Aplet123

Reputation: 35560

From the docs on BufRead::lines:

The iterator returned from this function will yield instances of io::Result<String>. Each string returned will not have a newline byte (the 0xA byte) or CRLF (0xD, 0xA bytes) at the end.

(emphasis mine)

Your line variable is a Result<String>, yet you try to call re.is_match on it like it's a string. Since your main function already returns a Result, the cleanest solution is to use the ? operator (pronounced "try operator") to return an Err whenever any line is an Err:

for line in reader.lines() {
    println!("{}", re.is_match(&line?));
}

You also need &line instead of line, since the function takes &str, not String.

Upvotes: 4

Zan Lynx
Zan Lynx

Reputation: 54355

You could also do this with a filter_map operation on the iterator. I am sure there is some way to reduce the number of operations here, but this is what I got...

extern crate regex;
use regex::Regex;

use std::fs::File;
use std::io::{BufRead, BufReader, Result};

fn main() -> Result<()> {
    let file = File::open("logs.log")?;
    let reader = BufReader::new(file);

    let re = Regex::new(r"^\w{3}\s{1,2}\d{1,2}\s(?:\d{2}:){2}\d{2}").unwrap();

    reader
        .lines()
        .filter_map(Result::ok)
        .filter(|line| re.is_match(line))
        .for_each(|line| println!("{}", line));

    Ok(())
}

Upvotes: 1

grian
grian

Reputation: 318

The reason you're getting this error is because you haven't unwrapped the line, simply change your print line to

println!("{}", line.unwrap());

and it should work.

This error is unrelated to regex.

Upvotes: 1

Related Questions