我正在尝试学习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
函数应该在这种情况下使用,但我可能错了。
谢谢!
您可以轻松地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的包装器。
我知道它不会直接回答您的问题,因为它不直接使用take_while
,但您可以在character::complete::digit1
中使用digit1
解析器。
它采用一个&str
并消耗 [0..9] 中的 1 位或多位数字并返回一个&str
使用 nom 的 AsChar 特征的最新解决方案:
take_while1(AsChar::is_dec_digit)(input)