grexはライブラリであると同時にコマンドライン ユーティリティでもあり、正規表現を作成するという複雑で退屈な作業を簡素化することを目的としています。これは、ユーザーが提供したテスト ケースから単一の正規表現を自動的に生成することによって行われます。結果の式は、生成元のテスト ケースと一致することが保証されます。
このプロジェクトは、Devon Govett によって作成された JavaScript ツールregexgenの Rust ポートとして開始されました。さらに多くの便利な機能が追加される可能性がありましたが、その開発は数年前に中止されたようです。コマンドラインツールに関してはRustが真に優れているため、これらの新機能をgrexに追加することが現在計画されています。 grex は、 regexgen が提供するすべての機能などを提供します。
このプロジェクトの理念は、指定された入力のみに正確に一致し、他には何も一致しない、可能な限り最も具体的な正規表現をデフォルトで生成することです。コマンドライン フラグ (CLI ツール内) または前処理メソッド (ライブラリ内) を使用すると、より一般化された式を作成できます。
生成される式は Perl 互換の正規表現であり、Rust の正規表現クレートの正規表現パーサーとも互換性があります。他の正規表現パーサーや他のプログラミング言語のライブラリはこれまでのところテストされていませんが、同様にほぼ互換性があるはずです。
間違いなく、そうです!標準設定を使用すると、 grex は、入力として指定されたテスト ケースのみに一致し、それ以外には一致しないことが保証される正規表現を生成します。これは特性試験によって確認されています。ただし、 w
などの短縮文字クラスへの変換が有効な場合、結果として得られる正規表現は、より広範囲のテスト ケースに一致します。ビジネス ドメインに適した正規表現を見つけるには、この変換の結果に関する知識が不可欠です。
grex は、指定されたテスト ケースに対して可能な限り最短の正規表現を見つけようとするアルゴリズムを使用します。ただし、結果として得られる式が必要以上に長かったり、複雑だったりすることがよくあります。このような場合、よりコンパクトまたはエレガントな正規表現は手動でのみ作成できます。また、各正規表現エンジンにはさまざまな最適化が組み込まれています。 grex はそれらについて何も知らないため、特定のエンジン用に正規表現を最適化できません。
正規表現の書き方を学んでください。 grexの現時点での最良の使用例は、さらなる最適化が可能であれば手動で検査する必要がある初期の正しい正規表現を見つけることです。
{min,max}
量指定子表記への変換|
使用した代替オペレーター?
使用したオプション量指定子^
および$
上記のプラットフォーム用の自己完結型実行可能ファイルをダウンロードして、任意の場所に配置できます。あるいは、コンパイル済みの 64 ビット バイナリは、パッケージ マネージャー Scoop (Windows 用)、Homebrew (macOS および Linux 用)、MacPorts (macOS 用)、および Huber (macOS、Linux および Windows 用) 内で利用できます。 Raúl Piracés は Chocolatey Windows パッケージを提供しました。
grexは、Rust の公式パッケージ レジストリである crates.io でもホストされています。あなたがRust開発者で、すでにRustツールチェーンがインストールされている場合は、Rustパッケージマネージャーであるcargoを使用してソースからコンパイルすることでインストールできます。インストール オプションの概要は次のとおりです。
( brew | cargo | choco | huber | port | scoop ) install grex
grex をライブラリとして使用するには、それを依存関係としてCargo.toml
ファイルに追加するだけです。
[ dependencies ]
grex = { version = " 1.4.5 " , default-features = false }
依存関係の拍手はコマンドライン ツールでのみ必要です。デフォルトの機能を無効にすると、ライブラリに対する拍手のダウンロードとコンパイルが防止されます。
利用可能な設定の詳細な説明は、ライブラリのセクションに記載されています。すべての設定は自由に組み合わせることができます。
テスト ケースは、直接 ( grex abc
) またはファイルから ( grex -f test_cases.txt
) 渡されます。 grex は、Unix パイプラインからの入力も受け取ることができます。たとえば、 cat test_cases.txt | grex -
。
次の表に、使用可能なすべてのフラグとオプションを示します。
$ grex -h
grex 1.4.5
© 2019-today Peter M. Stahl
Licensed under the Apache License, Version 2.0
Downloadable from https://crates.io/crates/grex
Source code at https://github.com/pemistahl/grex
grex generates regular expressions from user-provided test cases.
Usage: grex [OPTIONS] {INPUT...|--file }
Input:
[INPUT]... One or more test cases separated by blank space
-f, --file Reads test cases on separate lines from a file
Digit Options:
-d, --digits Converts any Unicode decimal digit to d
-D, --non-digits Converts any character which is not a Unicode decimal digit to D
Whitespace Options:
-s, --spaces Converts any Unicode whitespace character to s
-S, --non-spaces Converts any character which is not a Unicode whitespace character to S
Word Options:
-w, --words Converts any Unicode word character to w
-W, --non-words Converts any character which is not a Unicode word character to W
Escaping Options:
-e, --escape Replaces all non-ASCII characters with unicode escape sequences
--with-surrogates Converts astral code points to surrogate pairs if --escape is set
Repetition Options:
-r, --repetitions
Detects repeated non-overlapping substrings and converts them to {min,max} quantifier
notation
--min-repetitions
Specifies the minimum quantity of substring repetitions to be converted if --repetitions
is set [default: 1]
--min-substring-length
Specifies the minimum length a repeated substring must have in order to be converted if
--repetitions is set [default: 1]
Anchor Options:
--no-start-anchor Removes the caret anchor `^` from the resulting regular expression
--no-end-anchor Removes the dollar sign anchor `$` from the resulting regular expression
--no-anchors Removes the caret and dollar sign anchors from the resulting regular
expression
Display Options:
-x, --verbose Produces a nicer-looking regular expression in verbose mode
-c, --colorize Provides syntax highlighting for the resulting regular expression
Miscellaneous Options:
-i, --ignore-case Performs case-insensitive matching, letters match both upper and lower case
-g, --capture-groups Replaces non-capturing groups with capturing ones
-h, --help Prints help information
-v, --version Prints version information
テスト ケースはRegExpBuilder::from()
を介してコレクションから、またはRegExpBuilder::from_file()
を介してファイルから渡されます。ファイルから読み取る場合、各テスト ケースは別の行になければなりません。行は、改行n
または改行付き復帰rn
のいずれかで終了できます。
use grex :: RegExpBuilder ;
let regexp = RegExpBuilder :: from ( & [ "a" , "aa" , "aaa" ] ) . build ( ) ;
assert_eq ! ( regexp , "^a(?:aa?)?$" ) ;
use grex :: RegExpBuilder ;
let regexp = RegExpBuilder :: from ( & [ "a" , "aa" , "123" ] )
. with_conversion_of_digits ( )
. with_conversion_of_words ( )
. build ( ) ;
assert_eq ! ( regexp , "^( \ d \ d \ d| \ w(?: \ w)?)$" ) ;
use grex :: RegExpBuilder ;
let regexp = RegExpBuilder :: from ( & [ "aa" , "bcbc" , "defdefdef" ] )
. with_conversion_of_repetitions ( )
. build ( ) ;
assert_eq ! ( regexp , "^(?:a{2}|(?:bc){2}|(?:def){3})$" ) ;
デフォルトでは、 grex は、少なくとも 1 文字の長さの各部分文字列をこの方法で変換し、その後少なくとも 1 回繰り返されます。必要に応じて、これら 2 つのパラメータをカスタマイズできます。
次の例では、繰り返される部分文字列a
の長さは 1 ですが、部分文字列の最小長が 2 に設定されているため、テスト ケースaa
はa{2}
に変換されません。
use grex :: RegExpBuilder ;
let regexp = RegExpBuilder :: from ( & [ "aa" , "bcbc" , "defdefdef" ] )
. with_conversion_of_repetitions ( )
. with_minimum_substring_length ( 2 )
. build ( ) ;
assert_eq ! ( regexp , "^(?:aa|(?:bc){2}|(?:def){3})$" ) ;
次の例では、最小繰り返し回数を 2 回に設定し、2 回繰り返される唯一のテスト ケースdefdefdef
のみが変換されます。
use grex :: RegExpBuilder ;
let regexp = RegExpBuilder :: from ( & [ "aa" , "bcbc" , "defdefdef" ] )
. with_conversion_of_repetitions ( )
. with_minimum_repetitions ( 2 )
. build ( ) ;
assert_eq ! ( regexp , "^(?:bcbc|aa|(?:def){3})$" ) ;
use grex :: RegExpBuilder ;
let regexp = RegExpBuilder :: from ( & [ "You smell like ?." ] )
. with_escaping_of_non_ascii_chars ( false )
. build ( ) ;
assert_eq ! ( regexp , "^You smell like \ u{1f4a9} \ .$" ) ;
古いバージョンの JavaScript は、アストラル コード プレーン (範囲U+010000
からU+10FFFF
) の Unicode エスケープ シーケンスをサポートしていません。 JavaScript 正規表現でこれらの記号をサポートするには、サロゲート ペアへの変換が必要です。この件についての詳細は、こちらをご覧ください。
use grex :: RegExpBuilder ;
let regexp = RegExpBuilder :: from ( & [ "You smell like ?." ] )
. with_escaped_non_ascii_chars ( true )
. build ( ) ;
assert_eq ! ( regexp , "^You smell like \ u{d83d} \ u{dca9} \ .$" ) ;
grex が生成する正規表現は、デフォルトでは大文字と小文字が区別されます。大文字と小文字を区別しないマッチングは次のように有効にできます。
use grex :: RegExpBuilder ;
let regexp = RegExpBuilder :: from ( & [ "big" , "BIGGER" ] )
. with_case_insensitive_matching ( )
. build ( ) ;
assert_eq ! ( regexp , "(?i)^big(?:ger)?$" ) ;
デフォルトでは、非キャプチャ グループが使用されます。前の例を拡張して、代わりにグループのキャプチャに切り替えることができます。
use grex :: RegExpBuilder ;
let regexp = RegExpBuilder :: from ( & [ "big" , "BIGGER" ] )
. with_case_insensitive_matching ( )
. with_capturing_groups ( )
. build ( ) ;
assert_eq ! ( regexp , "(?i)^big(ger)?$" ) ;
生成された正規表現が読みにくい場合は、冗長モードを有効にすることができます。次に、表現を複数の行に分けてインデントして、目に優しいものにします。
use grex :: RegExpBuilder ;
use indoc :: indoc ;
let regexp = RegExpBuilder :: from ( & [ "a" , "b" , "bcd" ] )
. with_verbose_mode ( )
. build ( ) ;
assert_eq ! ( regexp , indoc! (
r#"
(?x)
^
(?:
b
(?:
cd
)?
|
a
)
$"#
) ) ;
デフォルトでは、入力として指定されたテスト ケースのみに一致することを保証するために、生成されたすべての正規表現の周囲にアンカー^
と$
が配置されます。ただし、多くの場合、生成されたパターンをより大きなパターンの一部として使用することが望まれます。この目的のために、アンカーを個別に、または両方とも無効にすることができます。
use grex :: RegExpBuilder ;
let regexp = RegExpBuilder :: from ( & [ "a" , "aa" , "aaa" ] )
. without_anchors ( )
. build ( ) ;
assert_eq ! ( regexp , "a(?:aa?)?" ) ;
次の例は、サポートされているさまざまな正規表現構文機能を示しています。
$ grex a b c
^[a-c]$
$ grex a c d e f
^[ac-f]$
$ grex a b x de
^( ? :de | [abx])$
$ grex abc bc
^a ? bc$
$ grex a b bc
^( ? :bc ? | a)$
$ grex [a-z]
^ [ a - z ] $
$ grex -r b ba baa baaa
^b( ? :a{1,3}) ? $
$ grex -r b ba baa baaaa
^b( ? :a{1,2} | a{4}) ? $
$ grex y̆ a z
^( ? :y̆ | [az])$
Note:
Grapheme y̆ consists of two Unicode symbols:
U+0079 (Latin Small Letter Y)
U+0306 (Combining Breve)
$ grex " I ♥ cake " " I ♥ cookies "
^I ♥ c( ? :ookies | ake)$
Note:
Input containing blank space must be
surrounded by quotation marks.
文字列"I ♥♥♥ 36 and ٣ and ??."
コマンドライン表記を使用した次の例の入力として機能します。
$ grex < INPUT >
^I ♥♥♥ 36 and ٣ and ?? . $
$ grex -e < INPUT >
^I u {2665} u {2665} u {2665} 36 and u {663} and u {1f4a9} u {1f4a9} . $
$ grex -e --with-surrogates < INPUT >
^I u {2665} u {2665} u {2665} 36 and u {663} and u {d83d} u {dca9} u {d83d} u {dca9} . $
$ grex -d < INPUT >
^I ♥♥♥ dd and d and ?? . $
$ grex -s < INPUT >
^I s ♥♥♥ s 36 s and s ٣ s and s ?? . $
$ grex -w < INPUT >
^ w ♥♥♥ ww www w www ?? . $
$ grex -D < INPUT >
^ DDDDDD 36 DDDDD ٣ DDDDDDDD $
$ grex -S < INPUT >
^ S SSS SS SSS S SSS SSS $
$ grex -dsw < INPUT >
^ ws ♥♥♥ sddswwwsdswwws ?? . $
$ grex -dswW < INPUT >
^ wsWWWsddswwwsdswwwsWWW $
$ grex -r < INPUT >
^I ♥{3} 36 and ٣ and ?{2} . $
$ grex -er < INPUT >
^I u {2665}{3} 36 and u {663} and u {1f4a9}{2} . $
$ grex -er --with-surrogates < INPUT >
^I u {2665}{3} 36 and u {663} and ( ? : u {d83d} u {dca9}){2} . $
$ grex -dgr < INPUT >
^I ♥{3} d ( d and ){2}?{2} . $
$ grex -rs < INPUT >
^I s ♥{3} s 36 s and s ٣ s and s ?{2} . $
$ grex -rw < INPUT >
^ w ♥{3} w ( ? : w w {3} ){2}?{2} . $
$ grex -Dr < INPUT >
^ D {6}36 D {5}٣ D {8}$
$ grex -rS < INPUT >
^ S S ( ? : S {2} ){2} S {3} S S {3} S {3}$
$ grex -rW < INPUT >
^I W {5}36 W and W ٣ W and W {4}$
$ grex -drsw < INPUT >
^ ws ♥{3} sd ( ? : dsw {3} s ){2}?{2} . $
$ grex -drswW < INPUT >
^ wsW {3} sd ( ? : dsw {3} s ){2} W {3}$
自分でソース コードをビルドするには、Rust パッケージ マネージャーのCargoが利用できるように、安定した Rust ツールチェーンがマシンにインストールされている必要があります。注: CLI をビルドするには、Rust >= 1.70.0 が必要です。ライブラリ部分については、Rust < 1.70.0 で十分です。
git clone https://github.com/pemistahl/grex.git
cd grex
cargo build
ソース コードには、単体テスト、統合テスト、プロパティ テストで構成される広範なテスト スイートが付属しています。実行するには、次のように言うだけです。
cargo test
いくつかの設定のパフォーマンスを測定するベンチマークは、以下を使用して実行できます。
cargo bench
PyO3 と Maturin の助けを借りて、ライブラリは Python 拡張モジュールにコンパイルされているため、任意の Python ソフトウェア内でも使用できます。これは Python Package Index で入手でき、以下を使用してインストールできます。
pip install grex
Python 拡張モジュールを自分で構築するには、仮想環境を作成し、Maturin をインストールします。
python -m venv /path/to/virtual/environment
source /path/to/virtual/environment/bin/activate
pip install maturin
maturin build
Python ライブラリには、次のようにインポートできるRegExpBuilder
という名前の単一クラスが含まれています。
from grex import RegExpBuilder
このライブラリは WebAssembly (WASM) にコンパイルでき、これにより、ブラウザ内でも、Node.js で実行されているバックエンドでも、JavaScript ベースのプロジェクトでgrex を使用できるようになります。
コンパイルする最も簡単な方法はwasm-pack
使用することです。インストール後、たとえば、ブラウザーで直接使用できるように、Web ターゲットを使用してライブラリをビルドできます。
wasm-pack build --target web
これにより、このリポジトリの最上位にpkg
という名前のディレクトリが作成され、コンパイルされた wasm ファイルと JavaScript および TypeScript バインディングが含まれます。 HTML ファイルでは、たとえば次のようにgrex を呼び出すことができます。
< script type =" module " >
import init , { RegExpBuilder } from "./pkg/grex.js" ;
init ( ) . then ( _ => {
alert ( RegExpBuilder . from ( [ "hello" , "world" ] ) . build ( ) ) ;
} ) ;
script >
Node.js とブラウザー Chrome、Firefox、Safari の両方で利用できる統合テストもいくつかあります。それらを実行するには、次のように言うだけです。
wasm-pack test --node --headless --chrome --firefox --safari
Safari でテストの開始に失敗した場合は、まず次のコマンドを実行して Safari の Web ドライバーを有効にする必要があります。
sudo safaridriver --enable
wasm-pack
の出力は別のリポジトリでホストされ、JavaScript 関連の設定、テスト、ドキュメントをさらに追加できるようになります。 grexは npm レジストリにも追加され、すべての JavaScript または TypeScript プロジェクト内で簡単にダウンロードしてインストールできるようになります。
grex を試してみることができるデモ Web サイトがあります。
決定論的有限オートマトン (DFA) が入力文字列から作成されます。
DFA の状態と状態間の遷移の数は、Hopcroft の DFA 最小化アルゴリズムを適用することによって削減されます。
最小化された DFA は、Brzozowski の代数法で解かれた一連の線形方程式として表現され、最終的な正規表現が得られます。
予定されている問題を見てみましょう。
grexに何か貢献したい場合は、そうすることをお勧めします。素晴らしい機能のアイデアはありますか?それともこれまでに何かバグを発見しましたか?気軽にイシューを開いたりプルリクエストを送信したりしてください。大変感謝しております。 :-)