如果我不需要从0开始,如何找到子串的正确方法是什么?
我有这段代码:
fn SplitFile(reader: BufReader<File>) {
for line in reader.lines() {
let mut l = line.unwrap();
// l contains "06:31:53.012 index0:2015-01-06 00:00:13.084
...
我需要找到第三个:
并解析它背后的日期。仍然不知道怎么做,因为find
没有像begin
那样的任何参数 - 请参阅https://doc.rust-lang.org/std/string/struct.String.html#method.find。
(我知道我可以使用正则表达式。我已经完成了,但我想比较性能 - 手动解析是否比使用正则表达式更快。</ em>)
答案 0 :(得分:5)
在我看来,这个问题有一个更简单的解决方案,那就是使用.splitn()
方法。此方法最多n次按给定模式拆分字符串。例如:
let s = "ab:bc:cd:de:ef".to_string();
println!("{:?}", s.splitn(3, ':').collect::<Vec<_>>());
// ^ prints ["ab", "bc", "cd:de:ef"]
在您的情况下,您需要将行拆分为由':'
分隔的4个部分,并取第4个部分(从0开始索引):
// assuming the line is correctly formatted
let date = l.splitn(4, ':').nth(3).unwrap();
如果您不想使用展开(行可能没有正确格式化):
if let Some(date) = l.splitn(4, ':').nth(3) {
// parse the date and time
}
答案 1 :(得分:4)
你是对的,搜索字符串时似乎没有任何跳过几个匹配的简单方法。你可以手工完成。
fn split_file(reader: BufReader<File>) {
for line in reader.lines() {
let mut l = &line.as_ref().unwrap()[..]; // get a slice
for _ in 0..3 {
if let Some(idx) = l.find(":") {
l = &l[idx+1..]
} else {
panic!("the line didn't have enough colons"); // you probably shouldn't panic
}
}
// l now contains the date
...
<强>更新强>
当faiface指出below时,您可以使用splitn()
更清洁一点:
fn split_file(reader: BufReader<File>) {
for line in reader.lines() {
let l = line.unwrap();
if let Some(datetime) = l.splitn(4, ':').last() {
// datetime now contains the timestamp string
...
} else {
panic!("line doesn't contain a timestamp");
}
}
}
你应该回答他的答案。
答案 2 :(得分:1)
只是日期,而不是时间,对吗?
let test: String = "06:31:53.012 index0:2015-01-06 00:00:13.084".into();
let maybe_date = test.split_whitespace()
.skip(1)
.next()
.and_then(|substring| substring.split(":").skip(1).next());
assert_eq!(maybe_date, Some("2015-01-06"));