gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 11:35:57 28 4
gpt4 key购买 nike

我正在尝试解析字母字符的字符序列,包括德国变音符号(äöü)和其他来自UTF-8字符集的字母字符。
这是我首先尝试的解析器:

named!(
parse(&'a str) -> Self,
map!(
alpha1,
|s| Self { chars: s.into() }
)
);

但是它仅适用于ASCII字母字符(a-zA-Z)。
我试图通过 char执行 char的解析:

named!(
parse(&str) -> Self,
map!(
take_while1!(nom::AsChar::is_alpha),
|s| Self { chars: s.into() }
)
);

但这甚至不会解析“hello”,但会导致 Incomplete(Size(1))错误:

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

extern crate nom;

#[derive(PartialEq, Debug, Eq, Clone, Hash, Ord, PartialOrd)]
pub struct Word {
chars: String,
}

impl From<&str> for Word {
fn from(s: &str) -> Self {
Self {
chars: s.into(),
}
}
}

use nom::*;
impl Word {
named!(
parse(&str) -> Self,
map!(
take_while1!(nom::AsChar::is_alpha),
|s| Self { chars: s.into() }
)
);
}


#[test]
fn parse_word() {
let words = vec![
"hello",
"Hi",
"aha",
"Mathematik",
"mathematical",
"erfüllen"
];
for word in words {
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库的行为似乎并不像我期望的那样。我正在使用 nom 5.1.0

最佳答案

第一个标称5使用函数进行解析,我建议使用这种形式,因为错误消息要好得多,代码要干净得多。

您的要求很奇怪,您可以将完整的输入作为字符串输入:

impl Word {
fn parse(input: &str) -> IResult<&str, Self> {
Ok((
&input[input.len()..],
Self {
chars: input.to_string(),
},
))
}
}

但是我想您的目的是解析一个单词,所以这里有一个您可以做的例子:

#[derive(PartialEq, Debug, Eq, Clone, Hash, Ord, PartialOrd)]
pub struct Word {
chars: String,
}

impl From<&str> for Word {
fn from(s: &str) -> Self {
Self { chars: s.into() }
}
}

use nom::{character::complete::*, combinator::*, multi::*, sequence::*, IResult};

impl Word {
fn parse(input: &str) -> IResult<&str, Self> {
let (input, word) =
delimited(space0, recognize(many1_count(none_of(" \t"))), space0)(input)?;
Ok((
input,
Self {
chars: word.to_string(),
},
))
}
}

#[test]
fn parse_word() {
let words = vec![
"hello",
" Hi",
"aha ",
" Mathematik ",
" mathematical",
"erfüllen ",
];
for word in words {
assert_eq!(Word::parse(word).unwrap().1, Word::from(word.trim()));
}
}

您还可以创建一个使用 is_alphabetic() 而不是 none_of(" \t")的自定义函数,但这需要对nom进行自定义错误,而我认为目前这样做很烦人。

关于parsing - Rust-如何解析nom中的UTF-8字母字符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59690456/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com