[英]Take prefix slice of &str that matches `Pattern` in rust
My ultimate goal is to parse the prefix number of a &str
if there is one.我的最终目标是解析&str
的前缀号(如果有的话)。 So I want a function that given "123abc345"
will give me a pair (u32, &str)
which is (123, "abc345")
.所以我想要一个 function 给定"123abc345"
会给我一对(u32, &str)
这是(123, "abc345")
。
My idea is that if I have a Pattern
type I should be able to do something like我的想法是,如果我有一个Pattern
类型,我应该能够做类似的事情
/// `None` if there is no prefix in `s` that matches `p`,
/// Otherwise a pair of the longest matching prefix and the rest
/// of the string `s`.
fn split_prefix<P:Pattern<'a>(s: &'a str, p: P) -> Option<(&'a str, &'a str)>;
My goal would be achieved by doing something like我的目标将通过做类似的事情来实现
let num = if let Some((num_s, rest)) = split_prefix(s, char::is_digit) {
s = rest;
num_s.parse()
}
What's the best way to get that?获得它的最佳方法是什么?
I looked at the source for str::split_once
and modified slightly to inclusively return a greedily matched prefix.我查看了str::split_once
的源代码并稍作修改以包含返回一个贪婪匹配的前缀。
#![feature(pattern)]
use std::str::pattern::{Pattern, Searcher};
/// See source code for `std::str::split_once`
fn split_prefix<'a, P: Pattern<'a>>(s: &'a str, p: P) -> Option<(&'a str, &'a str)> {
let (start, _) = p.into_searcher(s).next_reject()?;
// `start` here is the start of the unmatched (rejected) substring, so that is our sole delimiting index
unsafe { Some((s.get_unchecked(..start), s.get_unchecked(start..))) }
// If constrained to strictly safe rust code, an alternative is:
// s.get(..start).zip(s.get(start..))
}
This generic prefix splitter could then be wrapped in a specialized function to parse out numerical prefixes:然后可以将此通用前缀拆分器包装在专用的 function 中以解析数字前缀:
fn parse_numeric_prefix<'a>(s: &'a str) -> Option<(u32, &'a str)> {
split_prefix(s, char::is_numeric)
.map(|(num_s, rest)| num_s.parse().ok().zip(Some(rest)))
.flatten()
}
UPDATE: I just re-read your question and realized you want a None
when there is no prefix match.更新:我刚刚重新阅读了你的问题并意识到当没有前缀匹配时你想要一个None
。 Updated functions:更新功能:
fn split_prefix<'a, P: Pattern<'a>>(s: &'a str, p: P) -> Option<(&'a str, &'a str)> {
let (start, _) = p.into_searcher(s).next_reject()?;
if start == 0 {
None
} else {
unsafe { Some((s.get_unchecked(..start), s.get_unchecked(start..))) }
}
}
fn parse_numeric_prefix<'a>(s: &'a str) -> Option<(u32, &'a str)> {
split_prefix(s, char::is_numeric)
// We can unwrap the bare `Result` now since we know there's a
// matched numeric which will parse
.map(|(num_s, rest)| (num_s.parse().unwrap(), rest))
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.