简体   繁体   English

如何按 nom 解析匹配的分隔符?

[英]How to parse matched separators by nom?

I want to parse YMD date in four forms ("20190919", "2019.09.19", "2019-09-19", and "2019/09/19") by nom library.我想通过nom库解析四个 forms(“20190919”、“2019.09.19”、“2019-09-19”和“2019/09/19”)中的 YMD 日期。

I started with iso8601 parser which parse only "YYYY-MM-DD" form.我从iso8601解析器开始,它只解析“YYYY-MM-DD”形式。 And I tryed to match separator and reuse it for next matching like in regex (\d{4})([.-/]?)(\d{2})\2(\d{2}) .我尝试匹配分隔符并将其重用于下一次匹配,如正则表达式(\d{4})([.-/]?)(\d{2})\2(\d{2})

Turned out that this code works:原来这段代码有效:

fn parse_ymd(i: &[u8]) -> IResult<&[u8], DateType> {
    let (i, y) = year(i)?;

    // Match separator if it exist.
    let (i, sep) = opt(one_of(".-/"))(i)?;

    let (i, m) = month(i)?;

    // If first separator was matched then try to find next one.
    let (i, _) = if let Some(sep) = sep {
        tag(&[sep as u8])(i)?
    } else {
        // Support the same signature as previous branch.
        (i, &[' ' as u8][..])
    };

    let (i, d) = day(i)?;

    Ok((
        i,
        DateType::YMD {
            year: y,
            month: m,
            day: d,
        },
    ))
}

But obviously it looks weird.但显然它看起来很奇怪。

Are there some nom tools to do it more appropriate way?是否有一些 nom 工具可以以更合适的方式进行操作?

(This question about nom functionality, and how to do things there right. Not about just this particular example.) (这个关于nom功能的问题,以及如何在那里正确地做事。不仅仅是这个特定的例子。)

Your solution is decent enough.您的解决方案足够体面。 There is only one suggestion I can offer really:我只能提供一个建议:

fn parse_ymd(i: &[u8]) -> IResult<&[u8], DateType> {
    ...

    // If first separator was matched then try to find next one.
    let i = match sep {
        Some(sep) => tag(&[sep as u8])(i)?.0,
        _ => i,
    };

    ...
}

You may not be familiar with the syntax of accessing a tuple element directly.您可能不熟悉直接访问元组元素的语法。 From rust book :来自rust 书

In addition to destructuring through pattern matching, we can access a tuple element directly by using a period (.) followed by the index of the value we want to access.除了通过模式匹配进行解构之外,我们还可以通过使用句点 (.) 后跟我们要访问的值的索引来直接访问元组元素。

In this case, it saves you the awkwardness of trying to match the signature of two arms.在这种情况下,它可以避免尝试匹配两个手臂的签名的尴尬。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM