如何使用 nom take_while 和 is_digit 作为 &str 输入

How to use nom take_while and is_digit for a &str input

我正在尝试学习 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 解析器采用 &str 它将抱怨类型不匹配。但是有没有可能以某种方式使用 is_digit 呢?我可以在某处进行类型转换而不必分配任何东西吗?我真的希望它尽可能高效。

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

谢谢!

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

中使用 digit1 解析器

它需要一个 &str 并在 [0..9] 和 returns 中消耗 1 个或多个数字 &str

您可以轻松地将 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)
}

你也可以使用特征方法is_dec_digit, which is just a wrapper for char.is_digit