Rust 入門 簡単な関数を書いてみる(4)

Rust入門の続き

住所から都道府県と市区町村を抜き出す関数はできたので、次は番地と建物を抜き出す必要があるが、その前に番地等の表記ゆれを正規化するために、漢数字をアラビア数字に変換する関数を書く。

Rust でも、PascalC#みたいに関数内関数を書けるのだな。 三項演算子と同様、経験的に使う人と使わない人がはっきり分かれる機能だと思うけど、僕は結構好んで使う方だ。

// 漢数字をアラビア数字に変換する
fn kanji_numeral_to_arabic_numerals(s: &str) -> String {

    // 漢数字を半角数字に置換する
    fn z2h(s: &str) -> String {
        s.replace("一", "1")
        .replace("壱", "1")
        .replace("1", "1")
        .replace("二", "2")
        .replace("弐", "2")
        .replace("2", "2")
        .replace("三", "3")
        .replace("参", "3")
        .replace("3", "3")
        .replace("四", "4")
        .replace("4", "4")
        .replace("五", "5")
        .replace("5", "5")
        .replace("六", "6")
        .replace("6", "6")
        .replace("七", "7")
        .replace("7", "7")
        .replace("八", "8")
        .replace("8", "8")
        .replace("九","9")
        .replace("9", "9")
        .replace("〇", "0")
        .replace("0", "0")
    };

    // 変換処理
    fn convert(s: &str, re: Regex) -> i64 {

        let mut digits: HashMap<&str, i64> = HashMap::new();
        digits.insert("十", 10);
        digits.insert("拾", 10);
        digits.insert("百", 100);
        digits.insert("千", 1000);
        digits.insert("万", 10000);
        digits.insert("億", 100000000);
        digits.insert("兆", 1000000000000);

        let reg_arabic_numerals:Regex = Regex::new("^[0-9]+$").unwrap();

        let mut unit:i64 = 1;
        let mut result:i64 = 0;
        for piece in re.find_iter(s).map(|m| m.as_str()).collect::<Vec<&str>>().iter().rev() {
            if digits.contains_key(piece) {
                if unit > 1 {
                    result += unit;
                }
                unit = digits[piece];
            } else {
                if reg_arabic_numerals.is_match(piece) {
                    result += piece.parse::<i64>().unwrap() * unit;
                } else {
                    let reg_divide_digit_unit:Regex = Regex::new("[十拾百千]|\\d+").unwrap();
                    result += convert(piece, reg_divide_digit_unit) * unit;
                };
                unit = 1;            
            }
        }
        result
    };
    
    convert(&z2h(s), Regex::new("[万億兆]|[^万億兆]+").unwrap()).to_string()
}