rustparser-combinatorsnom

How to use nom to gobble a string until a delimiter or the end?


I'm learning nom, and as a test example I'm trying to parse a string until a delimiter. If my delimiter is /, then I want to match everything until that delimiter. For that, a parser like this works:

named!(gobbledygook, take_until!("/"));

I also want to match a string that ends before that delimiter, so I want both foo/bar and foo to return "foo". I can't seem to find anything suitable in the list of parsers and combinators.

I guess it would be possible to scan for either the delimiter or the end of the string, but it seems this is such a common case that there should be something obvious that I'm missing.


Solution

  • You can do this with the take_while! macro. This code:

    #[macro_use]
    extern crate nom;
    
    use nom::types::CompleteStr
    
    named!(gobbledygook<CompleteStr, CompleteStr>,
        take_while!(|ch| ch != '/')
    );
    
    fn main() {
        println!("1: {}", gobbledygook(CompleteStr("foo/bar")).unwrap().1);
        println!("2: {}", gobbledygook(CompleteStr("foo")).unwrap().1);
    }
    

    prints:

    1: foo
    2: foo
    

    Note that you need to use CompleteStr to tell nom that foo is the full string (ie. there is no risk the full string is actually foofoo/bar in which cas the returned value would be different). See this document for details about CompleteStr: https://github.com/Geal/nom/blob/master/doc/upgrading_to_nom_4.md#dealing-with-incomplete-usage