[英]How do I change characters at a specific index within a string in rust?
我正在嘗試更改字符串中特定索引處的單個字符,但我不知道如何在 rust 中更改。 例如,如何將“hello world”中的第 4 個字符更改為“x”,這樣它就變成了“helxo world”?
最簡單的方法是像這樣使用replace_range()
方法:
let mut hello = String::from("hello world");
hello.replace_range(3..4,"x");
println!("hello: {}", hello);
Output: hello: helxo world
( 游樂場)
請注意,如果要替換的范圍不在 UTF-8 代碼點邊界上開始和結束,則會出現恐慌。 例如這會恐慌:
let mut hello2 = String::from("hell😀 world");
hello2.replace_range(4..5,"x"); // panics because 😀 needs more than one byte in UTF-8
如果要替換第 n 個 UTF-8 代碼點,則必須執行以下操作:
pub fn main() {
let mut hello = String::from("hell😀 world");
hello.replace_range(
hello
.char_indices()
.nth(4)
.map(|(pos, ch)| (pos..pos + ch.len_utf8()))
.unwrap(),
"x",
);
println!("hello: {}", hello);
}
( 游樂場)
在 Rust 中表示字符串的標准方法是編碼為 UTF-8 字符串的連續字節范圍。 UTF-8 代碼點的長度可以是 1 到 4 個字節,因此通常不能簡單地將一個 UTF-8 代碼點替換為另一個代碼點,因為長度可能會改變。 您也不能進行簡單的指針運算來索引 Rust String
到第 n 個字符,因為代碼點編碼的長度可以是 1 到 4 個字節。
因此,一種安全但緩慢的方法是這樣的,遍歷源字符串的字符,替換您想要的字符,然后創建一個新字符串:
fn replace_nth_char(s: &str, idx: usize, newchar: char) -> String {
s.chars().enumerate().map(|(i,c)| if i == idx { newchar } else { c }).collect()
}
但是如果我們手動確保舊字符和新字符是單字節 ascii,我們可以在 O(1) 中做到這一點。
fn replace_nth_char_safe(s: &str, idx: usize, newchar: char) -> String {
s.chars().enumerate().map(|(i,c)| if i == idx { newchar } else { c }).collect()
}
fn replace_nth_char_ascii(s: &mut str, idx: usize, newchar: char) {
let s_bytes: &mut [u8] = unsafe { s.as_bytes_mut() };
assert!(idx < s_bytes.len());
assert!(s_bytes[idx].is_ascii());
assert!(newchar.is_ascii());
// we've made sure this is safe.
s_bytes[idx] = newchar as u8;
}
fn main() {
let s = replace_nth_char_safe("Hello, world!", 3, 'x');
assert_eq!(s, "Helxo, world!");
let mut s = String::from("Hello, world!");
replace_nth_char_ascii(&mut s, 3, 'x');
assert_eq!(s, "Helxo, world!");
}
請記住, replace_nth_char_ascii
中的idx
參數不是字符索引,而是字節索引。 如果字符串前面有任何多字節字符,則字節索引和字符索引將不對應。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.