メロディー:regexへの新しい方法


今日yoav-lavi 発表Melody , ECMAScript regexにコンパイルする言語.今、私は多くのregexを書くので、このプロジェクトはすぐに私の興味をかき回しました.
プロジェクトは数日前にリリースされたので、いくつかの重要な機能が不足している.例えば、できません.
  • フラグを設定するi 大文字小文字を区別しない場合はu Unicodeのサポートについてはg グローバルサーチなど
  • negate範囲(例:/[^A]/ )
  • 任意のマルチ範囲を作成します./[a-c1-3]/ )
  • 変数を渡す( JavaScriptではなく、regex )
  • すべてが言った、構文はかなり滑らかです.ここでは、文字列のハッシュタグを見つけるためのドキュメントの簡単な例を示します.
    "#";
    some of <word>;
    
    以下に出力の正規表現を示します:
    /#(?:\w)+/
    
    構文は面白いです、しかし、あなたがRegexを知らないならば、あなたは無限により読みやすいメロディー版を見つけると主張します.

    面白い構文


    メロディーがレジュックスをより読みやすく、より多くの人間が読むことができるようにする方法のいくつかについて話しましょう、そして、より少ない呪文を制定する目的のために汚れにルーンを描くために、血を使ってください.

    シンボル


    Symbols メロディの方法は、多くの一般的なregexタスクを単純化することです.たとえば、任意の場合、任意の通常のラテン文字をキャプチャする場合は、書き込み可能性があります[a-zA-Z] . メロディでも、あなたは<alphabetic> シンボル!この文章には16シンボルがありますが、ここではいくつかのお気に入りです.
  • <char>ワイルドカードの代替. ) 文字にマッチします.<char> すべての推測を考え出すの仕事アウトかかる\\\. はワイルドカードかリテラル期間文字です.🙃
  • <word>Regexのエスケープコードは非常に便利ですが、それは常に彼らがやっていることは明らかではない.The <word> シンボルは任意の単語文字にマッチします.これは\w Regexのエスケープコード.
  • <alphanumeric>ラテン文字にマッチするA-Z ) いずれにせよa-z ), 数字だけでなく0-9 ). これは使用と同じです[a-zA-Z0-9] regexで.
  • 特殊記号


    この執筆時点では、2つの特殊記号があります.<start> and <end> . これらの記号は^ and $ 文字それぞれ.検索は文字列の先頭または末尾から開始しなければならないことを示すのに使われる.

    数量詞


    Quantifiers 私たちを許してください.まあ、彼らは私たちの式を定量化することができます.例えば、UUIDをregexでチェックするためにこのようなものを使うことができます.
    /^\w{8}-\w{4}-\w{4}-\w{4}-\w{12}$/
    
    こちらです.{8} , {4} , and {12} はすべての量指定子です.前の検索の正確に8 , 4 , 12が欲しいことを示します.メロディでは、これは... of ... 数量指定子:
    <start>;
    8 of <word>;
    "-";
    4 of <word>;
    "-";
    4 of <word>;
    "-";
    4 of <word>;
    "-";
    12 of <word>;
    <end>;
    
    特定の範囲内の文字の数を必要とする場合は、使用することができます{min,max} . 例えば、\d{1,2} は、1と2桁の間を望むことを示します.メロディは... to ... of ... 数量指定子:
    1 to 2 of <digit>;
    
    メロディーはまた、* (ゼロ以上)+ (一つ以上)? (ゼロまたは1 )数量指定子:
    // \d*
    any of <digit>;
    
    // \d+
    some of <digit>;
    
    // \d?
    option of <digit>;
    

    文字範囲


    既知の文字集合内の何かを探すとき、文字範囲を使う必要がある[0-9a-f] ). 範囲の宣言は... to ... エクスプレッション.
    // [a-f]
    a to f;
    
    // [1-5]
    1 to 5;
    

    グループ


    Regexの最も重要な機能の一つは、グループです!キャプチャと非キャプチャグループは非常に複雑な検索を作成することが可能になります.メロディーはこれらを可能にするcapture , match , and either グループ
    メジャー、マイナー、パッチのバージョンをキャプチャするにはsemver 文字列:
    capture major {
      some of <digit>;
    }
    
    ".";
    
    capture minor {
      some of <digit>;
    }
    
    ".";
    
    capture patch {
      some of <digit>;
    }
    
    あなたがそれをキャプチャせずに検索に一致する必要がある場合は、使用することができますmatch . あなたが複数に加わる必要があるならばmatch ステートメントを一緒に使用することができますeither . ここでは、2つの桁16進値にマッチするためにマルチ範囲の不足を扱うために両方を使用します.
    2 of match {
      either {
        0 to 9;
        a to f;
      }
    }
    

    これ以上!


    メロディは他の機能の多くをサポートしているので、確認してくださいcheck out the docs !

    メロディーをペースにする


    基本的な例はクールで、すべてですが、読みやすさの引数がまだ保持されているかどうかを見るために、実際の世界の正規表現をメロディに変換したいと思っています.

    簡単なテスト


    私のゲームに取り組んでいる間debug ) 最近、私はゲームパッドから名前、ベンダーID、および製品IDをつかむためにregexを書きました.私が書いたオリジナルのバージョンは次のようになります.
    /^(.*?) \((?:standard gamepad )?vendor: (\w+) product: (\w+)\)$/ui
    
    メロディに変換した唯一の問題はメロディがフラグをサポートしていないことですu (ユニコード)i (大文字小文字を区別しない)フラグが変換されません.今のところ、私はメロディの正規表現に渡す前に、文字列上でそれを扱うことができますが、それは心の中に保つためにかなりの不足をdeffoです.
    それ以上のADOがなければ、私のオリジナルの正規表現がメロディ構文に変換されます.
    <start>;
    
    capture {
      lazy any of <char>;
    }
    
    <space>;
    "(";
    
    option of match {
      "standard gamepad ";
    }
    
    "vendor: ";
    
    capture {
      some of <word>;
    }
    
    <space>;
    "product: ";
    
    capture {
      some of <word>;
    }
    
    ")";
    
    <end>;
    
    これは、元の正規表現よりも多くの詳細ですが、それは我々が欲しいものです!あなたが既に正規表現を読む方法を知っているならば、結果として生じるメロディー・バージョンは確かにより元の正規表現より読みやすいです、そして、それはメロディー版がより読みやすいかどうかについて議論します.
    良い方法では、しかし、メロディから出力と一緒にオリジナルの正規表現のサイドバイサイドを行いましょう
    // Original
    /^(.*?) \((?:standard gamepad )?vendor: (\w+) product: (\w+)\)$/ui
    
    // Melody
    /^(.*?) \((?:standard gamepad )?vendor: ((?:\w)+)product: ((?:\w)+)\)$/
    
    私が気づいた奇妙なことは、メロディが必要以上に非キャプチャグループを追加する傾向があることです.例えば、オリジナルとメロディの出力の唯一の違いは\w エスケープコードは余分な非キャプチャグループにラップされています.それは完全に不要です、私はmade an issue レポについて

    もっと複雑になりましょう


    昨年私は不合理なパスワード検証の課題に遭遇.あなたの行動で私のソリューションを見ることができますRegExr.com , しかし、実際に私が思い付いた正規表現です.
    /(?:.*(?:(?:[A-Z].*(?:[0-9].*[a-z]|[a-z].*[0-9]))|(?:[a-z].*(?:[A-Z].*[0-9]|[0-9].*[A-Z]))|(?:[0-9].*(?:[A-Z].*[a-z]|[a-z].*[A-Z]))).*)/
    
    毎回、私は戻って、それを読みます.🤢
    このregexが読むのがとても不可能であるという事実は、私がメロディーのための読みやすさの大きいテストであると思ったまさに理由です.メロディバージョンがどのように見えるかを見てみましょう.
    match {
      any of <char>;
    
      either {
        match {
          A to Z;
          any of <char>;
    
          either {
            match {
              0 to 9;
              any of <char>;
              a to z;
            }
    
            match {
              a to z;
              any of <char>;
              0 to 9;
            }
          }
        }
    
        match {
          a to z;
          any of <char>;
    
          either {
            match {
              A to Z;
              any of <char>;
              0 to 9;
            }
    
            match {
              0 to 9;
              any of <char>;
              A to Z;
            }
          }
        }
    
        match {
          0 to 9;
          any of <char>;
    
          either {
            match {
              A to Z;
              any of <char>;
              a to z;
            }
    
            match {
              a to z;
              any of <char>;
              A to Z;
            }
          }
        }
      }
    
      any of <char>;
    }
    
    それでたくさん噛んでください.しかし、それは否定的に元の正規表現よりも読みやすいです!出力についての1つの警告は、最後の例で述べた問題がまだ不必要な非捕捉グループであるということです.そうでなければ、出力は完璧です!❤️

    最後の思考


    メロディは、JavaScriptエコシステムに優れた追加されるようだ!それは行く方法を持っています、しかし、私はそれが成熟する方法を見るために個人的に興奮しています.
    場合にYoav これを読んでいると、Lemmeは私が見てlooove何を教えてください:私はあなたの.melody ファイルは、私はimport myRegex from './my-regex.melody' 使用myRegex 直接正規代理店の代わりに!テンプレート文字列の中でメロディを書くことができるBabelプラグインがありますが、完全に別々のファイルでそれを書くことができて、それがカスタムウェブパック・ローダーまたはrolulupプラグインを通して輸入されるのを驚くべきであるでしょう.あなたがそのプロジェクトをペアにしたいならば.🥳