你如何逐个字符地迭代

时间:2014-03-01 18:08:04

标签: string iterator rust

我有一个字符串,我需要扫描每次出现的“foo”并读取其后的所有文本,直到第二个"由于Rust没有字符串<{s}的contains函数,我需要通过字符扫描来迭代它。我该怎么做?

修改:Rust的&strcontains()find()方法。

2 个答案:

答案 0 :(得分:69)

  

我需要通过字符扫描来进行迭代。

.chars() method返回字符串中字符的迭代器。例如

for c in my_str.chars() { 
    // do something with `c`
}

for (i, c) in my_str.chars().enumerate() {
    // do something with character `c` and index `i`
}

如果您对每个字符的字节偏移感兴趣,可以使用char_indices

查看.peekable(),并使用peek()进行展望。它是这样包装的,因为它支持UTF-8代码点,而不是简单的字符向量。

你也可以创建一个char的向量并从那里开始工作,但这需要更多的时间和空间:

let my_chars: Vec<_> = mystr.chars().collect();

答案 1 :(得分:2)

“字符”的概念非常模糊,根据您使用的数据类型,它可能意味着许多不同的东西。最明显的答案是 chars 方法。然而,这并不像宣传的那样工作。对您来说看起来像单个“字符”的内容实际上可能由多个 Unicode 代码点组成,这可能会导致意想不到的结果:

"a̐".chars() // => ['a', '\u{310}']

对于实际的字符串处理,您需要使用 graphemes。一个字素由一个或多个表示为字符串切片的 unicode 代码点组成。这些映射更好地映射到人类对“字符”的感知。要创建字素迭代器,您可以使用 unicode-segmentation crate:

use unicode_segmentation::UnicodeSegmentation;

for grapheme in my_str.graphemes(true) {
    // ...
}

如果您使用的是原始 ASCII,那么以上都不适用于您,您可以简单地使用 bytes 迭代器:

for byte in my_str.bytes() {
    // ...
}

虽然,如果您使用的是 ASCII,那么可以说您根本不应该使用 String/&str,而是使用 Vec<u8>/&[u8] 或 {{ 3}} 板条箱。