🛞

Rustに`Regex::try_replace_all`が導入されることはなさそうなので自分で書くべし

2024/03/17に公開

regex crateRegex::replace_allを使えば、正規表現にマッチした文字列に応じた柔軟な文字列置換が可能です。が、これは失敗に対応していないという問題があり、「特定パターンの文字列を置換したいが、その中でも特にこのパターンの場合はエラーにしたい」というユースケースには使えないので困る。不正パターン検出と置換の2パスでやればいいけど冗長になるので一発でやりたいやろが。

という問い合わせがしばしばあったようで、よく見たら公式ドキュメントに「そういうのは提供してないんで自分でやってね」と書いてありました…… API suggestionのissue書き始めてから気づいたよ。
というわけで、公式ドキュメントにあるこのスニペットをコピペするのが現状だと最速なようです。

fn replace_all<E>(
    re: &Regex,
    haystack: &str,
    replacement: impl Fn(&Captures) -> Result<String, E>,
) -> Result<String, E> {
    let mut new = String::with_capacity(haystack.len());
    let mut last_match = 0;
    for caps in re.captures_iter(haystack) {
        let m = caps.get(0).unwrap();
        new.push_str(&haystack[last_match..m.start()]);
        new.push_str(&replacement(&caps)?);
        last_match = m.end();
    }
    new.push_str(&haystack[last_match..]);
    Ok(new)
}

クソ記事を読んでくれてありがとうございます。いかがでしたか?

Discussion