4

我正在尝试学习 nom 并且在take_while不接受is_digit或任何其他方面遇到问题is_xxxx

我有要解析的行看起来像这样

#123 = ABCDEF (...);

我想在哪里获得“123”部分(最终还有 ABCDEF 和 (...) 部分。但我猜当时有一件事)。

我的解析器目前看起来像这样

use nom::{
  bytes::complete::take_while,
  character::is_digit,
  error::ParseError,
  IResult
};

// Get row id
fn id<'a, E: ParseError<&'a str>>(i: &'a str) -> IResult<&'a str, &'a str, E> {
    take_while(is_digit)(i)
}

is_digit定义看起来像这样

pub fn is_digit(chr: u8) -> bool

并且由于id解析器采用 a&str它会抱怨类型不匹配。但是无论如何有可能以某种方式使用 is_digit 吗?我可以在某处进行类型转换而无需分配任何东西。我真的希望这尽可能高效。

感觉提供的is_xxxx功能应该在这种情况下使用,但我可能错了。

谢谢!

4

2 回答 2

3

您可以轻松is_digit适应char. 首先,所有数字都是有效的 ASCII,所以我们应该首先检查字符是否是 ASCII。如果它是 ASCII,我们可以安全地转换为u8.

// pub fn is_digit(chr: u8) -> bool;

pub fn is_char_digit(chr: char) -> bool {
    return chr.is_ascii() && is_digit(chr as u8)
}

您还可以使用 trait 方法is_dec_digit,它只是char.is_digit的包装器。

于 2019-09-05T20:35:57.037 回答
2

我知道它不会直接回答您的问题,因为它不会直接使用take_while,但您可以digit1character::complete::digit1.

它需要一个&str并消耗 [0..9] 中的 1 个或多个数字并返回一个&str

于 2019-09-05T20:35:36.077 回答