Capture A Match That Is Not Followed By A String In Rust's nom
The goal of this parser is to match everything up to a specific string. Right no it returns a Vec
of &str
that can be joined. I'm trying to figure out if there's a way to flatten it and return a single &str
.
I don't have a specific need to get to the &str
. Mainly I'm curious to see if it can be done and thereby keep &str
all the way up. If not, I'll do the conversion of the final Vec
into a String
for the return value of get_up_to()
```cargo
[dependencies]
nom = "7.1.3"
```
use nom::bytes::complete::tag_no_case;
use nom::bytes::complete::take_until;
use nom::combinator::not;
use nom::sequence::pair;
use nom::sequence::terminated;
use nom::IResult;
fn get_up_to<'a>(source: &'a str, target: &'a str) -> IResult<&'a str, Vec<&'a str>> {
let mut result = vec![];
let (source, captured) = (|src| get_part(src, target))(source)?;
result.push(captured.0);
result.push(captured.1);
Ok((source, result))
}
fn get_part<'a>(source: &'a str, target: &'a str) -> IResult<&'a str, (&'a str, &'a str)> {
let (source, captured) = terminated(
pair(take_until(target), tag_no_case(target)),
not(tag_no_case(target)),
)(source)?;
Ok((source, captured))
}
fn main() {
let tests = vec![("alfa bravo charlie", "bravo", " charlie", "alfa bravo"), ];
for test in tests.iter() {
let result = get_up_to(test.0, test.1).unwrap();
assert_eq!(result.0, test.2, "Check remainder");
assert_eq!(result.1.join(""), test.3, "Check captured");
}
println!("All Tests Passed");
}