我有一个String(特别是一个SHA1十六进制摘要),我想分成两个子串 - 前两个字符和字符串的其余部分。在Rust中有一个干净的方法吗?
答案 0 :(得分:6)
如果您知道您的字符串只包含ASCII字符(如sha摘要的情况),您可以直接使用切片:
let s = "13e3f28a65a42bf6258cbd1d883d1ce3dac8f085";
let first = &s[..2]; // "13"
let rest = &s[2..]; // "e3f28a65a42bf6258cbd1d883d1ce3dac8f085"
如果您的字符串包含非ASCII字符,它将无法正常工作,因为切片使用字节偏移,并且如果切片中使用的任何索引指向代码点表示的中间,您的程序将会发生混乱。
答案 1 :(得分:2)
如果您期望两个String
而不是切片,则可以使用chars()
方法和一些Iterator
方法来获取它们。
let text = "abcdefg".to_string();
let start: String = text.chars().take(2).collect();
let end: String = text.chars().skip(2).collect();
如果您不想进行堆分配,可以改为使用切片:
let start: &str = text.slice_chars(0, 2);
let end: &str = text.slice_chars(2, text.char_len());
请注意,切片版本要求您使用不稳定的生锈(每晚构建,而不是测试版)
答案 2 :(得分:2)
自Rust 1.4以来,有一个split_at方法,请按照以下方式使用:
let s = "13e3f28a65a42bf6258cbd1d883d1ce3dac8f085";
let (first, last) = s.split_at(2);
assert_eq!("13", first);
assert_eq!("e3f28a65a42bf6258cbd1d883d1ce3dac8f085", last);
请注意,索引是一个字节位置,必须位于字符边界上。在这种情况下,这是有效的,因为您知道您的输入字符串是ASCII。
答案 3 :(得分:1)
如果您拥有此拥有的字符串数据大小写,以下是一种有效地将字符串拆分为两个字符串的方法。通过使用截断,输入字符串的分配将保留在第一部分中。
/// Split a **String** at a particular index
///
/// **Panic** if **byte_index** is not a character boundary
fn split_string(mut s: String, byte_index: usize) -> (String, String)
{
let tail = s[byte_index..].into();
s.truncate(byte_index);
(s, tail)
}
注意: .into()方法来自通用转换特征进入,在这种情况下,它会转换& str 进入字符串。