我想在Rust中创建一个子字符串。它从一个字符串的出现开始,在字符串的末尾减去四个字符或某个字符处结束。
我的第一个方法是
string[string.find("pattern").unwrap()..string.len()-5]
这是错误的,因为Rust的字符串是有效的UTF-8,因此是基于字节而不是基于字符的。
我的第二种方法是正确的,但过于冗长:
let start_bytes = string.find("pattern").unwrap();
let mut char_byte_counter = 0;
let result = line.chars()
.skip_while(|c| {
char_byte_counter += c.len_utf8();
return start_bytes > char_byte_counter;
})
.take_while(|c| *c != '<')
.collect::<String>();
有更简单的方法来创建子字符串吗?标准库中有没有我没有找到的部分?
3条答案
按热度按时间6pp0gazn1#
我不记得其他语言中有哪个内置库函数能完全按照你的要求工作(给予我两个模式之间的子字符串,或者如果第二个模式不存在,给我第一个和最后一个之间的子字符串),我想你无论如何都得写一些自定义逻辑。
与“子字符串”函数最接近的等价物是切片。(正如您所发现的)它处理字节,而不是unicode字符,所以您必须小心索引。(字节)索引4,而不是3(playground)。但是您仍然可以在您的情况下使用它,因为您不是直接使用索引(而是使用
find
来...找到您需要的索引)下面是如何使用切片来实现这一点(额外的好处是,您不需要重新分配其他
String
):jjhzyzn02#
尝试使用类似以下的方法:
kqlmhetl3#
考虑到字符和字素,这个方法近似于O(n)。它可以工作,但我不确定是否有任何bug。