1

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.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
janneb
  • 36,249
  • 2
  • 81
  • 97

1 Answers1

3

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

Valentin Lorentz
  • 9,556
  • 6
  • 47
  • 69
  • Thanks, got it to work with this. Or well, I had to use CompleteByteSlice since I'm using bytes rather than strings. – janneb Jan 03 '19 at 20:44