grex adalah perpustakaan serta utilitas baris perintah yang dimaksudkan untuk menyederhanakan tugas yang seringkali rumit dan membosankan dalam membuat ekspresi reguler. Ia melakukannya dengan secara otomatis menghasilkan satu ekspresi reguler dari kasus uji yang disediakan pengguna. Ekspresi yang dihasilkan dijamin cocok dengan kasus uji yang menghasilkan ekspresi tersebut.
Proyek ini dimulai sebagai port Rust dari alat JavaScript regexgen yang ditulis oleh Devon Govett. Meskipun banyak fitur berguna yang dapat ditambahkan ke dalamnya, pengembangannya tampaknya terhenti beberapa tahun yang lalu. Rencananya sekarang adalah menambahkan fitur-fitur baru ini ke grex karena Rust benar-benar unggul dalam hal alat baris perintah. grex menawarkan semua fitur yang disediakan regexgen , dan banyak lagi.
Filosofi dari proyek ini adalah untuk menghasilkan ekspresi reguler sespesifik mungkin secara default yang hanya cocok dengan masukan yang diberikan dan tidak ada yang lain. Dengan menggunakan tanda baris perintah (di alat CLI) atau metode prapemrosesan (di perpustakaan), ekspresi yang lebih umum dapat dibuat.
Ekspresi yang dihasilkan adalah ekspresi reguler yang kompatibel dengan Perl yang juga kompatibel dengan parser ekspresi reguler di peti regex Rust. Parser ekspresi reguler lainnya atau pustaka masing-masing dari bahasa pemrograman lain belum diuji sejauh ini, tetapi sebagian besarnya juga harus kompatibel.
Tentu saja ya! Dengan menggunakan pengaturan standar, grex menghasilkan ekspresi reguler yang dijamin hanya cocok dengan kasus uji yang diberikan sebagai masukan dan tidak ada yang lain. Ini telah diverifikasi oleh tes properti. Namun, jika konversi ke kelas karakter steno seperti w
diaktifkan, regex yang dihasilkan cocok dengan cakupan kasus pengujian yang jauh lebih luas. Pengetahuan tentang konsekuensi konversi ini penting untuk menemukan ekspresi reguler yang tepat untuk domain bisnis Anda.
grex menggunakan algoritma yang mencoba menemukan regex terpendek untuk kasus uji yang diberikan. Namun seringkali, ekspresi yang dihasilkan masih lebih panjang atau lebih kompleks dari yang seharusnya. Dalam kasus seperti itu, regex yang lebih ringkas atau elegan hanya dapat dibuat dengan tangan. Selain itu, setiap mesin ekspresi reguler memiliki pengoptimalan bawaan yang berbeda. grex tidak tahu apa-apa tentang hal itu dan oleh karena itu tidak dapat mengoptimalkan regexnya untuk mesin tertentu.
Jadi, silakan pelajari cara menulis ekspresi reguler! Kasus penggunaan terbaik saat ini untuk grex adalah menemukan regex awal yang benar yang harus diperiksa secara manual jika pengoptimalan lebih lanjut memungkinkan.
{min,max}
|
operator?
pembilang^
dan $
Anda dapat mengunduh executable mandiri untuk platform Anda di atas dan meletakkannya di tempat pilihan Anda. Alternatifnya, biner 64-Bit yang telah dikompilasi sebelumnya tersedia dalam manajer paket Scoop (untuk Windows), Homebrew (untuk macOS dan Linux), MacPorts (untuk macOS), dan Huber (untuk macOS, Linux dan Windows). Raúl Piracés telah menyumbangkan paket Chocolatey Windows.
grex juga dihosting di crates.io, registri paket Rust resmi. Jika Anda adalah pengembang Rust dan sudah menginstal toolchain Rust, Anda dapat menginstal dengan mengkompilasi dari sumber menggunakan cargo , manajer paket Rust. Jadi ringkasan opsi instalasi Anda adalah:
( brew | cargo | choco | huber | port | scoop ) install grex
Untuk menggunakan grex sebagai perpustakaan, cukup tambahkan sebagai dependensi ke file Cargo.toml
Anda:
[ dependencies ]
grex = { version = " 1.4.5 " , default-features = false }
Tepuk ketergantungan hanya diperlukan untuk alat baris perintah. Dengan menonaktifkan fitur default, pengunduhan dan kompilasi clap dicegah untuk perpustakaan.
Penjelasan rinci tentang pengaturan yang tersedia disediakan di bagian perpustakaan. Semua pengaturan dapat digabungkan secara bebas satu sama lain.
Kasus uji dilewatkan secara langsung ( grex abc
) atau dari file ( grex -f test_cases.txt
). grex juga dapat menerima inputnya dari pipeline Unix, misalnya cat test_cases.txt | grex -
.
Tabel berikut memperlihatkan semua tanda dan opsi yang tersedia:
$ 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
Kasus uji diteruskan baik dari koleksi melalui RegExpBuilder::from()
atau dari file melalui RegExpBuilder::from_file()
. Jika dibaca dari sebuah file, setiap test case harus berada pada baris terpisah. Baris dapat diakhiri dengan baris baru n
atau gerbong kembali dengan umpan baris 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})$" ) ;
Secara default, grex mengonversi setiap substring dengan cara ini yang panjangnya setidaknya satu karakter dan kemudian diulangi setidaknya sekali. Anda dapat menyesuaikan kedua parameter ini jika Anda mau.
Dalam contoh berikut, kasus uji aa
tidak dikonversi menjadi a{2}
karena substring berulang a
memiliki panjang 1, namun panjang substring minimum telah ditetapkan ke 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})$" ) ;
Menetapkan jumlah minimal 2 pengulangan pada contoh berikutnya, hanya test case defdefdef
yang akan dikonversi karena hanya test case yang diulang dua kali.
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 versi lama tidak mendukung rangkaian escape unicode untuk bidang kode astral (rentang U+010000
hingga U+10FFFF
). Untuk mendukung simbol-simbol ini dalam ekspresi reguler JavaScript, diperlukan konversi ke pasangan pengganti. Informasi lebih lanjut mengenai hal tersebut dapat ditemukan di sini.
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} \ .$" ) ;
Ekspresi reguler yang dihasilkan grex peka huruf besar-kecil secara default. Pencocokan peka huruf besar-kecil dapat diaktifkan seperti ini:
use grex :: RegExpBuilder ;
let regexp = RegExpBuilder :: from ( & [ "big" , "BIGGER" ] )
. with_case_insensitive_matching ( )
. build ( ) ;
assert_eq ! ( regexp , "(?i)^big(?:ger)?$" ) ;
Grup yang tidak menangkap digunakan secara default. Memperluas contoh sebelumnya, Anda dapat beralih ke pengambilan grup.
use grex :: RegExpBuilder ;
let regexp = RegExpBuilder :: from ( & [ "big" , "BIGGER" ] )
. with_case_insensitive_matching ( )
. with_capturing_groups ( )
. build ( ) ;
assert_eq ! ( regexp , "(?i)^big(ger)?$" ) ;
Jika Anda merasa ekspresi reguler yang dihasilkan sulit dibaca, Anda dapat mengaktifkan mode verbose. Ekspresi tersebut kemudian dibuat dalam beberapa baris dan dibuat menjorok ke dalam agar lebih enak dipandang.
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
)
$"#
) ) ;
Secara default, jangkar ^
dan $
diletakkan di sekitar setiap ekspresi reguler yang dihasilkan untuk memastikan bahwa ekspresi tersebut hanya cocok dengan kasus uji yang diberikan sebagai masukan. Namun seringkali pola yang dihasilkan diinginkan untuk digunakan sebagai bagian dari pola yang lebih besar. Untuk tujuan ini, jangkar dapat dinonaktifkan, baik secara terpisah atau keduanya.
use grex :: RegExpBuilder ;
let regexp = RegExpBuilder :: from ( & [ "a" , "aa" , "aaa" ] )
. without_anchors ( )
. build ( ) ;
assert_eq ! ( regexp , "a(?:aa?)?" ) ;
Contoh berikut menunjukkan berbagai fitur sintaksis regex yang didukung:
$ 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.
String "I ♥♥♥ 36 and ٣ and ??."
berfungsi sebagai masukan untuk contoh berikut menggunakan notasi baris perintah:
$ 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}$
Untuk membuat kode sumber sendiri, Anda memerlukan rantai alat Rust yang stabil yang diinstal pada mesin Anda sehingga kargo , manajer paket Rust tersedia. Harap diperhatikan : Rust >= 1.70.0 diperlukan untuk membangun CLI. Untuk bagian perpustakaan, Rust <1.70.0 sudah cukup.
git clone https://github.com/pemistahl/grex.git
cd grex
cargo build
Kode sumber disertai dengan rangkaian pengujian ekstensif yang terdiri dari pengujian unit, pengujian integrasi, dan pengujian properti. Untuk menjalankannya, cukup ucapkan:
cargo test
Benchmark yang mengukur kinerja beberapa pengaturan dapat dijalankan dengan:
cargo bench
Dengan bantuan PyO3 dan Maturin, perpustakaan telah dikompilasi ke modul ekstensi Python sehingga dapat digunakan dalam perangkat lunak Python apa pun juga. Ini tersedia di Indeks Paket Python dan dapat diinstal dengan:
pip install grex
Untuk membuat sendiri modul ekstensi Python, buat lingkungan virtual dan instal Maturin.
python -m venv /path/to/virtual/environment
source /path/to/virtual/environment/bin/activate
pip install maturin
maturin build
Pustaka Python berisi satu kelas bernama RegExpBuilder
yang dapat diimpor seperti:
from grex import RegExpBuilder
Pustaka ini dapat dikompilasi ke WebAssembly (WASM) yang memungkinkan penggunaan grex dalam proyek berbasis JavaScript apa pun, baik itu di browser atau di back end yang berjalan di Node.js.
Cara termudah untuk mengkompilasi adalah dengan menggunakan wasm-pack
. Setelah instalasi, Anda bisa, misalnya, membangun perpustakaan dengan target web sehingga bisa langsung digunakan di browser:
wasm-pack build --target web
Ini membuat direktori bernama pkg
di tingkat atas repositori ini, berisi file wasm yang dikompilasi serta pengikatan JavaScript dan TypeScript. Dalam file HTML, Anda kemudian dapat memanggil grex seperti berikut, misalnya:
< script type =" module " >
import init , { RegExpBuilder } from "./pkg/grex.js" ;
init ( ) . then ( _ => {
alert ( RegExpBuilder . from ( [ "hello" , "world" ] ) . build ( ) ) ;
} ) ;
script >
Ada juga beberapa tes integrasi yang tersedia untuk Node.js dan untuk browser Chrome, Firefox dan Safari. Untuk menjalankannya, cukup ucapkan:
wasm-pack test --node --headless --chrome --firefox --safari
Jika pengujian gagal dimulai di Safari, Anda harus mengaktifkan driver web Safari terlebih dahulu dengan menjalankan:
sudo safaridriver --enable
Output dari wasm-pack
akan dihosting di repositori terpisah yang memungkinkan untuk menambahkan konfigurasi, pengujian, dan dokumentasi terkait JavaScript lebih lanjut. grex kemudian akan ditambahkan ke registri npm juga, memungkinkan pengunduhan dan pemasangan yang mudah dalam setiap proyek JavaScript atau TypeScript.
Ada situs demo yang tersedia di mana Anda dapat mencoba grex.
Sebuah robot terbatas deterministik (DFA) dibuat dari string masukan.
Jumlah negara bagian dan transisi antar negara bagian dalam DFA dikurangi dengan menerapkan algoritma minimalisasi DFA Hopcroft.
DFA yang diperkecil dinyatakan sebagai sistem persamaan linier yang diselesaikan dengan metode aljabar Brzozowski, sehingga menghasilkan ekspresi reguler akhir.
Lihatlah masalah yang direncanakan.
Jika Anda ingin menyumbangkan sesuatu ke grex , saya mendorong Anda untuk melakukannya. Apakah Anda punya ide untuk fitur keren? Atau apakah Anda menemukan bug sejauh ini? Jangan ragu untuk membuka masalah atau mengirim permintaan penarikan. Ini sangat dihargai. :-)