Reputation: 615
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
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
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
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