我有一个字符串,我需要扫描每次出现的“foo”并读取其后的所有文本,直到第二个"
。 由于Rust没有字符串<{s}的contains
函数,我需要通过字符扫描来迭代它。我该怎么做?
修改:Rust的&str
有contains()
和find()
方法。
答案 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}} 板条箱。