Rustでregexをパターンマッチングできるライブラリを作った

Rustでregexをパターンマッチングできるライブラリを作った
TaKO8Ki
February 14, 2021

regexmというライブラリを作りました。

複数パターンの正規表現をif-elseでいちいちRegex::new(pattern).unwrap().is_match(str)するのが面倒くさくて、さっと書きたいなと思ったのが動機です。

img

使い方

基本的にRustのパターンマッチと同じように使うことができます。

fn main() {
    let text1 = "2020-01-01";
    regexm::regexm!(match text1 {
        r"^\d{4}$" => println!("yyyy"),
        r"^\d{4}-\d{2}$" => println!("yyyy-mm"),
        // block
        r"^\d{4}-\d{2}-\d{2}$" => {
            let yyyy_mm_dd = "yyyy-mm-dd";
            println!("{}", yyyy_mm_dd);
        }
        _ => println!("default"),
    });

    // Output: yyyy-mm-dd

    let text2 = "foo";
    let foo = regexm::regexm!(match text2 {
        r"^\d{4}-\d{2}-\d{2}$" => "yyyy-mm-dd",
        r"^\d{4}-\d{2}$" => "yyyy-mm",
        // block
        r"^\d{4}-\d{2}-\d{2}$" => {
            let yyyy_mm_dd = "yyyy-mm-dd";
            yyyy_mm_dd
        }
        _ => "default",
    });
    println!("{}", foo);

    // Output: default
}

また、Redditに投稿したところ「Capture groupsあったら良さそう」というコメントをもらったので、追加してみました。

fn main() {
    let text1 = "2020-01-02";
    regexm::regexm!(match text1 {
        captures(r"^(\d{4})-(\d{2})-(\d{2})$") => |caps| println!(
            "year: {}, month: {}, day: {}",
            caps.get(1).map_or("", |m| m.as_str()),
            caps.get(2).map_or("", |m| m.as_str()),
            caps.get(3).map_or("", |m| m.as_str())
        ),
        _ => println!("default"),
    });

    // Output:
    // 2020
    // 01
    // 02
}

以上です。詳しくは、exampleを見てください。

最近rustdocにコミットしてみたいと思っているので、良さそうなIssueを探してPR出してみようと思います。