簡體   English   中英

如何更改 rust 中字符串中特定索引處的字符?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM