🦀

Rust の文字列処理

2023/09/16に公開

Rust の文字列は2種類あります。&str と String。
ここでは &str について扱います。

共通の話題

&str はスライスなので、let substring = &some_string[1..5] のように切り出すことができます。
ただし、バイト列として扱うので、マルチバイト文字の途中を指定した場合はエラーになります。
例:

let s = "私は Rust が大好きです";
let sub_str = &s[1..5];  // panic error

そこで chars() を使うと Unicode 文字列のイテレータに変換されるので、&str が出てきたら何はともあれ chars() 、が定石のようです:

println!("{:?}", &s.chars());
println!("{:?}", 
// => Chars(['私', 'は', ' ', 'R', 'u', 's', 't', ' ', 'が', '大', '好', 'き', 'で', 'す'])

N番目の一文字を取得する

nth() で N 番目を指定して取り出します:

fn main() {
    let s = "私は Rust が大好きです";

    let t = s.chars().nth(1).unwrap(); 
    println!("{}", t);
    // => "は"
}

以後 let s = "私は Rust が大好きです" とします

末尾の一文字を取得する

let c = s.chars().last().unwrap();
println!("{}", c);

文字列の長さ

日本語混じりの場合は、一文字が2バイト以上になるので、len()count() で結果が異なる:

let len1 = s.len();  // 文字列のバイト数
let len2 = s.chars().count();  // 文字数
println!("len={}, count={}", len1, len2);
// => len=30, count=14

N文字目からM文字を取得する

skip() で N 文字読み飛ばして、take() で M 文字を取得します

let sub: String = s.chars().skip(1).take(5).collect();
println!("{}", sub);
// => "は Rus"

特定の文字で区切る

let v: Vec<_> = s.split(" ").collect();
println!("{:?}", v);
// => ["私は", "Rust", "が大好きです"]

特定の文字の出現位置

let pos = s.chars().position(|c| c == 'が');
println!("{:?}", pos);
// => Some(8)

空白文字の削除

trim() は全角空白も削除できます。

let s1 = " 私は Rust が大好きです \r\n";
let s2 = s1.trim();
println!("'{}'", s2);
// => '私は Rust が大好きです'

Python でいうところの lstrip, rstrip はそれぞれ trim_start(), trim_end() に相当する。

Discussion