Как сожрать нить до разделителя или до конца с ржавчиной / ном - PullRequest
0 голосов
/ 02 января 2019

Я изучаю nom, и в качестве тестового примера я пытаюсь разобрать строку до разделителя. Если мой разделитель, скажем, /, то я хочу сопоставить все до этого разделителя. Для этого парсер вроде

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

работает. Но я также хочу сопоставить строку, которая заканчивается перед этим разделителем. Поэтому я хочу, чтобы и foo/bar, и foo возвращали "foo". Кажется, я не могу найти ничего подходящего в списке на https://github.com/Geal/nom/blob/master/doc/choosing_a_combinator.md.

Полагаю, можно было бы отсканировать либо разделитель, либо конец строки, но, похоже, это настолько распространенный случай, что должно быть что-то очевидное, что я пропускаю?

1 Ответ

0 голосов
/ 02 января 2019

Вы можете сделать это с помощью макроса take_while!. Этот код:

#[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);
}

печать:

1: foo
2: foo

Обратите внимание, что вам нужно использовать CompleteStr, чтобы указать nom, что foo - полная строка (т. Е. Нет риска, что полная строка на самом деле foofoo/bar, в которой cas возвращаемое значение будет другим). См. Этот документ для деталей о CompleteStr: https://github.com/Geal/nom/blob/master/doc/upgrading_to_nom_4.md#dealing-with-incomplete-usage

...