String 如何在Rust中以惯用的方式高效地解析由字母和数字组成的字符串?

String 如何在Rust中以惯用的方式高效地解析由字母和数字组成的字符串?,string,split,rust,String,Split,Rust,我有一个字符串,后面跟一个数字,比如“R123”。字母不能保证为ASCII,解决方案不应依赖于utf-8编码。如何从中提取第一个字母,同时将数字转换为整数类型?当然,我希望这是惯用的和有效的 我尝试了几件事:如果我使用char\u index(),我可以split\u at()迭代一次后的位置,但随后我又得到了第一部分。我也可以使用chars()和collect()尾部,但这似乎效率低下 我还想以优雅的方式处理错误:我不想检查所有可能的组合(字母,但没有数字,等等),“要么全有,要么全无”的结果

我有一个字符串,后面跟一个数字,比如“R123”。字母不能保证为ASCII,解决方案不应依赖于utf-8编码。如何从中提取第一个字母,同时将数字转换为整数类型?当然,我希望这是惯用的和有效的

我尝试了几件事:如果我使用
char\u index()
,我可以
split\u at()
迭代一次后的位置,但随后我又得到了第一部分。我也可以使用
chars()
collect()
尾部,但这似乎效率低下


我还想以优雅的方式处理错误:我不想检查所有可能的组合(字母,但没有数字,等等),“要么全有,要么全无”的结果是可以的。

由于您不关心错误,我假设您需要签名
fn(&str)->选项的函数。您可以使用以下事实:
.chars()
返回一个迭代器,您可以将其转换回包含迭代器其余部分的
&str

fn parse(s: &str) -> Option<(char, i32)> {
    let mut iter = s.chars();
    iter.next().and_then(|c| {
        if c.is_alphabetic() {
            iter.as_str().parse().ok().map(|i| {
                (c, i)
            })
        } else {
            None
        }
    })
}
fn解析(s:&str)->选项{
设mut iter=s.chars();
iter.next()和| u then(| c |{
如果c.是字母(){
iter.as_str().parse().ok().map(|i|{
(c,i)
})
}否则{
没有一个
}
})
}

println!(“{:?}”,parse(“R1234”)
将打印
一些(('R',1234))
由于您不关心错误,我假设您需要签名
fn(&str)->选项的函数。您可以使用以下事实:
.chars()
返回一个迭代器,您可以将其转换回包含迭代器其余部分的
&str

fn parse(s: &str) -> Option<(char, i32)> {
    let mut iter = s.chars();
    iter.next().and_then(|c| {
        if c.is_alphabetic() {
            iter.as_str().parse().ok().map(|i| {
                (c, i)
            })
        } else {
            None
        }
    })
}
fn解析(s:&str)->选项{
设mut iter=s.chars();
iter.next()和| u then(| c |{
如果c.是字母(){
iter.as_str().parse().ok().map(|i|{
(c,i)
})
}否则{
没有一个
}
})
}

println!(“{:?}”,parse(“R1234”)
将打印
一些(('R',1234))

但这似乎是低效的-为什么您认为您的任何解决方案都是低效的?什么会让你相信我们给出的任何答案都是有效的?总是一封信吗?这个字母总是保证是ASCII码吗?@dirkt:你需要知道数据的编码。没有编码的字节和加密的字节一样好,没有合理的方法从中提取信息。请注意,“创建两个切片”是没有意义的,因为切片只是保存在堆栈上的(指针、长度)对。切片的创建是在线的,可以由编译器进行优化。如果有疑问,请使用
--emit=asm
选项检查生成的程序集。有关信息,我感觉问题来自:但这似乎效率低下-为什么您认为您的任何解决方案都效率低下?什么会让你相信我们给出的任何答案都是有效的?总是一封信吗?这个字母总是保证是ASCII码吗?@dirkt:你需要知道数据的编码。没有编码的字节和加密的字节一样好,没有合理的方法从中提取信息。请注意,“创建两个切片”是没有意义的,因为切片只是保存在堆栈上的(指针、长度)对。切片的创建是在线的,可以由编译器进行优化。如果有疑问,请使用
--emit=asm
选项检查生成的程序集。有关信息,我感觉问题来自:iter.as_str()
是如何实现的?它是否检测到它是一个字符串的尾部,并只是重复使用该尾部,还是构造一个新的
str
?您不能“构造”一个新的
str
&str
是一个字符串片段,它本质上是借用的。这样你就知道不会发生复制。相关文件在这里:哎呀,谢谢@Shepmaster。现在它不再那么优雅了,但仍然很好。是的,但如果OP能保证它总是以字母开头,那么支票就可以被删除。或者这是一个很好的机会。@Shepmaster:不管怎样都很好,我只是想知道如何去做。很好的解决方案。
iter.as\u str()
是如何实现的?它是否检测到它是一个字符串的尾部,并只是重复使用该尾部,还是构造一个新的
str
?您不能“构造”一个新的
str
&str
是一个字符串片段,它本质上是借用的。这样你就知道不会发生复制。相关文件在这里:哎呀,谢谢@Shepmaster。现在它不再那么优雅了,但仍然很好。是的,但如果OP能保证它总是以字母开头,那么支票就可以被删除。或者这是一个很好的机会。@Shepmaster:不管怎样都很好,我只是想知道如何去做。很好的解决方案。