繁体   English   中英

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

[英]How to parse matched separators by nom?

我想通过nom库解析四个 forms(“20190919”、“2019.09.19”、“2019-09-19”和“2019/09/19”)中的 YMD 日期。

我从iso8601解析器开始,它只解析“YYYY-MM-DD”形式。 我尝试匹配分隔符并将其重用于下一次匹配,如正则表达式(\d{4})([.-/]?)(\d{2})\2(\d{2})

原来这段代码有效:

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,
        },
    ))
}

但显然它看起来很奇怪。

是否有一些 nom 工具可以以更合适的方式进行操作?

(这个关于nom功能的问题,以及如何在那里正确地做事。不仅仅是这个特定的例子。)

您的解决方案足够体面。 我只能提供一个建议:

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,
    };

    ...
}

您可能不熟悉直接访问元组元素的语法。 来自rust 书

除了通过模式匹配进行解构之外,我们还可以通过使用句点 (.) 后跟我们要访问的值的索引来直接访问元组元素。

在这种情况下,它可以避免尝试匹配两个手臂的签名的尴尬。

暂无
暂无

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

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