在char之后的字符串中查找下一个char边界索引

时间:2017-04-07 12:31:48

标签: string char rust

给定字符串$('#year').on('change',function(){ var year = $(this).val(); $('#date').datepicker( "option", "minDate", new Date(year, 0, 1) ); $('#date').datepicker("option","maxDate", new Date(year,11,31)); }); ,以及s字符开始的索引i

在该字符后获取索引的最佳方法是什么,以便我可以对字符串进行切片并获得let s = "abc 好 def"; let i = 4; ?在代码中:

abc 好

(注意,let end = find_end(s, i); assert_eq!("abc 好", &s[0..end]); 不起作用,因为假设该字符只有1个字节长。)

我目前有以下内容:

+ 1

但是我想知道我是否错过了一些更好的方法?

2 个答案:

答案 0 :(得分:1)

您可以使用char_indices来获取下一个索引,而不是在角色上使用len_utf8,尽管这对最后一个角色有特殊情况。

我会使用方便的str::is_char_boundary()方法。这是使用它的实现:

fn find_end(s: &str, i: usize) -> usize {
    assert!(i < s.len());
    let mut end = i+1;
    while !s.is_char_boundary(end) {
        end += 1;
    }
    end
}

Playground link

通常我会使这样的函数返回Option<usize>,以防它在s结束时使用索引进行调用,但是现在我只是断言了。

在许多情况下,代替显式调用find_end,使用char_indices进行迭代可能是有意义的,它会为每个索引提供字符;虽然如果你想知道当前角色的结尾会有点烦人。

答案 1 :(得分:0)

作为@ ChrisEmerson答案的补充,这就是人们如何实现搜索角色第一次出现结束的find_endPlayground

fn find_end<'s>(s: &'s str, p: char) -> Option<usize> {
    let mut indices = s.char_indices();
    let mut found = false;
    for (_, v) in &mut indices {
        if v == p {
            found = true;
            break;
        }
    }
    if found {
        Some(indices.next()
                    .map_or_else(|| s.len(), |(i, _)| i))
    } else {
        None
    }
}

虽然它避免了字节边界循环,但它仍然不是很优雅。理想情况下,遍历直到满足谓词的迭代器方法可以简化这一过程。