Parsing Rust-如何解析nom中的UTF-8字母字符?

Parsing Rust-如何解析nom中的UTF-8字母字符?,parsing,utf-8,rust,nom,Parsing,Utf 8,Rust,Nom,我试图解析字母字符的字符序列,包括德语umlauts(äöü)和UTF-8字符集中的其他字母字符。 这是我首先尝试的解析器: 命名!( 解析(&'a str)->Self, 地图( 阿尔法1, |s|Self{chars:s.into()} ) ); 但它只适用于ASCII字母字符(a-zA-Z)。 我试图通过char执行解析char: 命名!( 解析(&str)->Self, 地图( 就拿“while1”来说吧!(名字::阿斯卡尔::是阿尔法), |s|Self{chars:s.into()

我试图解析字母字符的字符序列,包括德语umlauts(äöü)和UTF-8字符集中的其他字母字符。 这是我首先尝试的解析器:

命名!(
解析(&'a str)->Self,
地图(
阿尔法1,
|s|Self{chars:s.into()}
)
);
但它只适用于ASCII字母字符(a-zA-Z)。 我试图通过
char
执行解析
char

命名!(
解析(&str)->Self,
地图(
就拿“while1”来说吧!(名字::阿斯卡尔::是阿尔法),
|s|Self{chars:s.into()}
)
);
但这甚至不会解析“hello”,但会导致
不完整(大小(1))
错误:

如何解析中的UTF-8字母字符? 我的代码片段:

外部板条箱名称;
#[派生(PartialEq、Debug、Eq、Clone、Hash、Ord、PartialOrd)]
pub结构词{
字符:字符串,
}
从一个单词开始{
fn来自(s:&str)->Self{
自我{
chars:s.into(),
}
}
}
使用名称::*;
暗示词{
命名(
解析(&str)->Self,
地图(
就拿“while1”来说吧!(名字::阿斯卡尔::是阿尔法),
|s|Self{chars:s.into()}
)
);
}
#[测试]
fn parse_word(){
让文字=向量[
“你好”,
“嗨”,
“啊哈”,
“Mathematik”,
“数学”,
“埃尔弗伦”
];
一字不差{
assert_eq!(Word::parse(Word).unwrap().1,Word::from(Word));
}
}
当我运行这个测试时

cargo test parse_word
我得到:

thread panicked at 'called `Result::unwrap()` on an `Err` value: Incomplete(Size(1))', ...

我知道
char
s已经用Rust编码了UTF-8(谢天谢地,万能的),但是nom库的行为似乎不像我预期的那样。我正在使用

First nom 5 use函数进行解析,我建议使用此表单,因为错误消息更好,代码更干净

你的要求很奇怪,你可以把完整的输入变成一个字符串或更多:

impl单词{
fn解析(输入:&str)->IResult{
嗯((
&输入[input.len()…],
自我{
chars:input.to_string(),
},
))
}
}
但我猜你的目的是解析一个单词,所以这里有一个你可以做的例子:

#[派生(PartialEq、Debug、Eq、Clone、Hash、Ord、PartialOrd)]
pub结构词{
字符:字符串,
}
从一个单词开始{
fn来自(s:&str)->Self{
Self{chars:s.into()}
}
}
使用nom::{character::complete::*,combinator::*,multi::*,sequence::*,IResult};
暗示词{
fn解析(输入:&str)->IResult{
let(输入,单词)=
分隔符(空格0,识别(多个计数(“\t”)),空格0(输入)?;
嗯((
输入,
自我{
chars:word.to_string(),
},
))
}
}
#[测试]
fn parse_word(){
让文字=向量[
“你好”,
“嗨”,
“啊哈”,
“Mathematik”,
“数学”,
“埃尔富伦”,
];
一字不差{
assert_eq!(Word::parse(Word.unwrap().1,Word::from(Word.trim());
}
}

您也可以创建一个自定义函数来代替(“\t”)的none\u(“\t”),但这需要为nom生成一个自定义错误,并且在我看来,这是一个非常烦人的操作。

在这方面,一位同事很快创建了一个库()来很好地处理这个问题:

use nom_unicode::complete::{alphanumeric1};

impl Word {
    named!(
        parse(&'a str) -> Self,
        map!(
            alphanumeric1,
            |w| Self::new(w)
        )
    );
}

你真的应该使用上一个版本,它非常有用nicer@Boiethios你指的是哪个版本?第五个版本的API,正如另一个答案中所建议的。例如,您可以替换
贴图宏,等等。那么你的意思是我应该使用函数组合而不是宏组合?你说重点是什么?我对宏语法非常满意。