I'm trying to learn NOM for a project in Rust. I have a text file that consists of:
[tag="#43674"]char[/tag] with multiple tags back to back on each line. I'm trying to pull the '#43674' and 'char', store them in a tuple (x, y) and then push those into a vector Vec<(x, y)> for each line of the text file.
So far I have successfully combined parsers into two functions; one for the '#43674' and one for 'char' which I then combine together to return <IResult<&str, (String, String)>. Here is the code:
fn color_tag(i: &str) -> IResult<&str, &str> {
delimited(tag("[color="), take_until("]"), tag("]"))(i)
}
fn char_take(i: &str) -> IResult<&str, &str> {
terminated(take_until("[/color]"), tag("[/color]"))(i)
}
pub fn color_char(i: &str) -> IResult<&str, (String, String)> {
let (i, color) = color_tag(i)?;
let (i, chara) = char_take(i)?;
let colors = color.to_string();
let charas = chara.to_string();
let tuple = (colors, charas);
Ok((i, tuple))
}
How can I iterate this function over a given line of the text file? I already have a function that iterates the text file into lines, but I need color_char to repeat for each closure in that line. Am I missing the point entirely?
You'll probably want to use the
nom::multi::many0combinator to match a parser multiple times, and you can also use thenom::sequence::tuplecombinator to combine your color_tag and char_take parsersTo parse multiple lines, you can modify color_char() to match a trailing newline character with one of the character parsers provided by nom, such as
nom::character::complete::line_ending, make it optional usingnom::combinator::opt, and combine it with something likenom::sequence::terminated: