Ekspresi reguler pada dasarnya digunakan untuk memproses string, dan sangat mudah menggunakannya untuk mencocokkan, mengekstrak, dan mengganti string.
Namun, mempelajari ekspresi reguler masih terbilang sulit. Konsep seperti pencocokan serakah, pencocokan tidak serakah, subgrup penangkap, dan subgrup non-penangkapan tidak hanya sulit dipahami oleh pemula, tetapi juga bagi banyak orang yang telah bekerja selama beberapa tahun.
Jadi apa cara terbaik untuk mempelajari ekspresi reguler? Bagaimana cara cepat menguasai ekspresi reguler?
Saya merekomendasikan cara mempelajari aturan reguler yang menurut saya sangat baik: belajar melalui AST .
Prinsip pencocokan ekspresi reguler adalah mengurai string pola menjadi AST, dan kemudian menggunakan AST ini untuk mencocokkan string target.
Berbagai informasi dalam string pola akan disimpan di AST setelah diurai. AST adalah pohon sintaksis abstrak. Seperti namanya, ini adalah pohon yang disusun menurut struktur tata bahasa. Dari struktur AST, Anda dapat dengan mudah mengetahui sintaksis yang didukung oleh ekspresi reguler.
Bagaimana cara melihat AST dari ekspresi reguler?
Anda dapat melihatnya secara visual melalui website astexplorer.net:
Dengan mengalihkan bahasa parsing ke RegExp, Anda dapat memvisualisasikan AST ekspresi reguler.
Seperti disebutkan sebelumnya, AST merupakan pohon yang disusun menurut tata bahasa, sehingga berbagai tata bahasa dapat dengan mudah dipilah berdasarkan strukturnya.
Lalu mari kita pelajari berbagai sintaksis dari sudut pandang AST:
Mari kita mulai dengan yang sederhana. /abc/ Regular seperti itu dapat cocok dengan string 'abc', dan AST-nya adalah seperti ini:
3 Char, nilainya masing-masing a, b, c, tipenya sederhana. Pencocokan selanjutnya adalah melintasi AST dan mencocokkan ketiga karakter tersebut masing-masing.
Kami mengujinya menggunakan API exec:
Elemen ke-0 adalah string yang cocok, dan indeks adalah indeks awal dari string yang cocok. masukan adalah string masukan.
Mari kita coba karakter khusus lagi:
/ddd/ berarti mencocokkan tiga angka. d adalah metakarakter (meta char) dengan arti khusus yang didukung oleh ekspresi reguler.
Kita juga bisa melihat melalui AST bahwa walaupun mereka juga Char, tipe mereka memang meta:
Nomor apa pun dapat dicocokkan menggunakan metakarakter d:
Manakah karakter meta dan mana karakter sederhana dapat dilihat sekilas melalui AST.
Regular mendukung penentuan sekumpulan karakter melalui [], yang berarti dapat mencocokkan karakter mana pun.
Kita juga dapat melihat dari AST bahwa ia dibalut dengan lapisan CharacterClass yang artinya kelas karakter, yaitu dapat mencocokkan karakter apa pun yang dikandungnya.
Ini adalah kasus yang sedang diuji:
Ekspresi reguler mendukung penentuan berapa kali karakter tertentu diulang, menggunakan bentuk {from,to},
misalnya, /b{1,3}/ berarti karakter b diulang 1 hingga 3 kali , /[abc ]{1,3}/ berarti kelas karakter a/b/c ini diulang 1 hingga 3 kali.
Seperti dapat dilihat dari AST, sintaks ini disebut Pengulangan:
Ini memiliki atribut quantifier yang mewakili quantifier. Tipe di sini adalah rentang, dari 1 hingga 3.
Ekspresi reguler juga mendukung singkatan dari beberapa bilangan, seperti + yang menunjukkan 1 hingga waktu yang tak terhitung, * menunjukkan 0 hingga waktu yang tak terhitung, dan ? yang menunjukkan 0 atau 1 kali.
Mereka adalah berbagai jenis bilangan:
Beberapa siswa mungkin bertanya, apa yang dimaksud dengan sifat serakah di sini?
Greedy artinya serakah. Atribut ini menunjukkan apakah Pengulangan ini merupakan pertandingan yang serakah atau tidak.
Jika Anda menambahkan ? setelah pembilang, Anda akan menemukan bahwa serakah menjadi salah, yang berarti beralih ke pencocokan non-serakah:
Lalu apa yang dimaksud dengan serakah dan tidak serakah?
Mari kita lihat sebuah contoh.
Pencocokan Pengulangan default adalah serakah dan akan terus cocok selama kondisi terpenuhi, sehingga acbac dapat dicocokkan di sini.
Menambahkan ? setelah pembilang beralih ke non-serakah, dan hanya bilangan pertama yang akan cocok:
Ini adalah pencocokan serakah dan pencocokan tidak serakah. Melalui AST, kita dapat dengan jelas mengetahui bahwa serakah dan tidak serakah adalah untuk tata bahasa yang berulang. Defaultnya adalah pencocokan serakah.
ekspresi reguler mendukung penempatan bagian dari string yang cocok ke dalam subgrup dan mengembalikannya melalui ().
Lihatlah melalui AST:
AST yang sesuai disebut Grup.
Dan Anda akan menemukan bahwa ia memiliki atribut capture, yang defaultnya adalah true:
Apa artinya ini?
Ini adalah sintaks untuk penangkapan subgrup.
Jika Anda tidak ingin menangkap subkelompok, Anda dapat menulis seperti ini (?:aaa)
Lihat, penangkapan itu salah.
Apa perbedaan antara tangkap dan non-tangkap?
Mari kita coba:
Oh, ternyata atribut capture dari Group mewakili apakah akan diekstraksi atau tidak.
Kita dapat melihat dari AST bahwa capture adalah untuk subgrup. Defaultnya adalah capture, yang berarti konten subgrup diekstraksi. Anda dapat beralih ke non-capture melalui ?: dan konten subgrup tidak akan diekstraksi.
Kita sudah familiar dengan penggunaan AST untuk memahami sintaks reguler, tapi mari kita lihat sesuatu yang sedikit lebih sulit:
Ekspresi reguler mendukung ekspresi pernyataan ke depan melalui sintaks (?=xxx), yang digunakan untuk menilai karakter tertentu. Apakah string tersebut didahului oleh string tertentu.
Melalui AST terlihat sintaks ini disebut Assertion, dan tipenya adalah lookahead yang artinya melihat ke depan, hanya cocok dengan arti sebelumnya:
Apa artinya ini? Mengapa Anda menulis ini? Apa perbedaan antara /bbb(ccc)/ dan /bbb(?:ccc)/?
Mari kita mencobanya:
Hal ini dapat dilihat dari hasil:
/bbb(ccc)/ cocok dengan subgrup ccc dan mengekstrak subgrup ini karena subgrup default diambil.
/bbb(?:ccc)/ cocok dengan subgrup ccc tetapi tidak diekstraksi karena kami menyetel subgrup agar tidak ditangkap melalui ?:.
/bbb(?=ccc)/ Ccc yang cocok dengan subgrup tidak diekstraksi, yang menunjukkan bahwa subgrup tersebut juga tidak dapat ditangkap. Bedanya dengan ?: ccc tidak muncul di hasil pencocokan.
Ini adalah sifat dari pernyataan lookahead: pernyataan lookahead berarti bahwa string tertentu didahului oleh string tertentu, subgrup terkait tidak dapat ditangkap, dan string yang ditegaskan tidak akan muncul dalam hasil pencocokan.
Jika tidak diikuti oleh string tersebut, maka tidak akan cocok:
Ubah ?= menjadi ?! Lalu artinya berubah.
Meskipun pernyataan lookahead masih ditegaskan terlebih dahulu, ada tambahan atribut negatif yaitu benar.
Maknanya jelas, semula berarti bagian depan adalah string tertentu. Setelah dinegasikan, berarti bagian depan bukanlah string tertentu.
Maka hasil pencocokannya justru sebaliknya:
Sekarang ini hanya cocok jika bukan string tertentu di depannya. Ini adalah pernyataan pandangan ke depan yang negatif.
Jika ada pernyataan sebelumnya, tentu saja akan ada pernyataan tambahan, yaitu hanya cocok jika diikuti oleh string tertentu.
Dengan cara yang sama, dapat pula disangkal:
AST yang sesuai dengan (?<=aaa) mudah untuk dipikirkan, yaitu pernyataan di belakang:
AST yang sesuai dengan (?<!aaa) adalah menambahkan atribut negatif:
Pernyataan melihat ke depan dan pernyataan melihat ke belakang adalah sintaks ekspresi reguler yang paling sulit untuk dipahami. Apakah lebih mudah untuk memahaminya jika Anda mempelajarinya melalui AST ~
Ekspresi reguler adalah alat yang sangat nyaman untuk memproses string, tetapi masih agak sulit
untuk dipahami.sulit dipelajari. Banyak orang yang bingung tentang sintaksis seperti pencocokan serakah, pencocokan tidak serakah, subgrup yang menangkap, subgrup yang tidak menangkap, pernyataan melihat ke depan, pernyataan melihat ke belakang, dll.
Saya merekomendasikan mempelajari aturan reguler melalui AST. AST adalah pohon objek yang disusun menurut struktur tata bahasa. Berbagai sintaksis dapat dengan mudah diklarifikasi melalui nama dan atribut node AST.
Misalnya kita sudah klarifikasi melalui AST:
Sintaks pengulangan (Repetition) berbentuk karakter + quantifier, defaultnya adalah pencocokan serakah (serakah itu benar), artinya cocok sampai tidak ada yang cocok. Menambahkan ? -pencocokan serakah, berhenti ketika satu karakter cocok.
Sintaks subgrup (Grup) digunakan untuk mengekstrak string tertentu. Standarnya adalah menangkap (menangkap benar), yang berarti ekstraksi diperlukan. Anda dapat beralih ke non-menangkap melalui (?:xxx), yang hanya cocok tetapi tidak mengekstrak .
Sintaks pernyataan (Pernyataan) mewakili string tertentu sebelum atau sesudahnya. Ini dibagi menjadi pernyataan melihat ke depan dan pernyataan melihat ke belakang. Sintaksnya adalah (?=xxx) dan (?<=xxx) masing-masing negasi (negatif benar), yang artinya justru sebaliknya.
Apakah pemahaman mendalam tentang sintaksis di berbagai dokumen atau pemahaman mendalam tentang sintaksis di compiler?
Tidak perlu ditanya, itu pasti kompilernya!
Maka secara alami lebih baik mempelajari tata bahasa melalui pohon sintaksis yang diurai menurut tata bahasa daripada dokumen.
Hal ini berlaku untuk ekspresi reguler, dan juga berlaku untuk mempelajari tata bahasa lainnya. Jika Anda dapat mempelajari tata bahasa menggunakan AST, Anda tidak perlu membaca dokumentasinya.