JavaRush /Blog Java /Random-MS /RegEx: 20 langkah pendek untuk menguasai ungkapan biasa. ...
Artur
Tahap
Tallinn

RegEx: 20 langkah pendek untuk menguasai ungkapan biasa. Bahagian 2

Diterbitkan dalam kumpulan
RegEx: 20 langkah pendek untuk menguasai ungkapan biasa. Bahagian 1 Asal di sini Pada bahagian terakhir kami menguasai ungkapan biasa yang paling mudah, dan telah mempelajari sesuatu. Dalam bahagian ini kita akan mengkaji reka bentuk yang sedikit lebih kompleks, tetapi percayalah, ia tidak akan sesukar yang mungkin kelihatan. RegEx: 20 langkah pendek untuk menguasai ungkapan biasa.  Bahagian 2 - 1Jadi mari kita teruskan!

Langkah 8: Bintang *dan Tanda Tambah+

RegEx: 20 langkah pendek untuk menguasai ungkapan biasa.  Bahagian 2 - 2Setakat ini, kami lebih kurang hanya dapat memadankan rentetan dengan panjang tertentu. Tetapi dalam masalah terkini kami telah menghampiri had apa yang boleh kami lakukan dengan notasi yang telah kami lihat setakat ini. Mari kita anggap, sebagai contoh, bahawa kita tidak terhad kepada pengecam Java 3 aksara, tetapi kita boleh mempunyai pengecam dalam sebarang panjang. Penyelesaian yang mungkin berfungsi dalam contoh sebelumnya tidak akan berfungsi dalam contoh berikut:
corak: [a-zA-Z_$]\w\w 
rentetan:   __e $12 3 3.2 untuk Bar r a23 mm ab x
perlawanan: ^^^ ^^^ ^^^ ^^^  
( Contoh ) Notabahawa apabila pengecam sah tetapi lebih panjang daripada 3 aksara, hanya tiga aksara pertama dipadankan. Dan apabila pengecam itu sah, tetapi mengandungi kurang daripada 3 aksara, maka regex tidak menemuinya sama sekali! Masalahnya ialah ungkapan kurungan []sepadan dengan tepat satu aksara, begitu juga dengan kelas aksara seperti \w. Ini bermakna bahawa mana-mana padanan dalam ungkapan biasa di atas mestilah tepat tiga aksara panjang. Jadi ia tidak berfungsi dengan baik seperti yang kita harapkan. *Watak istimewa dan boleh membantu di sini +. Ini ialah pengubah suai yang boleh ditambah di sebelah kanan mana-mana ungkapan untuk memadankan ungkapan itu lebih daripada sekali. Bintang Kleene (atau "asterisk") *akan menunjukkan bahawa token sebelumnya mesti dipadankan beberapa kali, termasuk sifar kali. Tanda tambah +akan menunjukkan bahawa anda perlu mencari satu atau lebih kali. Oleh itu, ungkapan yang mendahului +adalah wajib (sekurang-kurangnya sekali), manakala ungkapan yang mendahului *adalah pilihan, tetapi apabila ia muncul, ia boleh muncul beberapa kali. Sekarang, dengan pengetahuan ini, kita boleh membetulkan ungkapan biasa di atas:
corak: [a-zA-Z_$]\w* 
rentetan:   __e $123 3.2 untuk Barr a23mm ab x 
padanan: ^^^ ^^^^ ^^ ^^^^ ^^^^^ ^^ ^ 
( Contoh ) Kini kami memadankan pengecam yang sah dalam sebarang panjang! Bingo! Tetapi apa yang akan berlaku jika kita +menggunakan *?
corak: [a-zA-Z_$]\w+ 
rentetan:   __e $123 3.2 untuk Barr a23mm ab x
perlawanan: ^^^ ^^^^ ^^ ^^^^ ^^^^^ ^^ 
( Contoh ) Kami terlepas perlawanan terakhir, х. Ini kerana ia memerlukan +sekurang-kurangnya satu aksara untuk dipadankan, tetapi memandangkan ungkapan dalam kurungan []sebelumnya \w+telah 'memakan' watak itu x, tiada lagi aksara yang tersedia, jadi padanan itu gagal. Bilakah kita boleh menggunakan +? Apabila kita perlu mencari sekurang-kurangnya satu padanan, tetapi tidak kira berapa kali ungkapan yang diberikan mesti sepadan. Sebagai contoh, jika kita ingin mencari sebarang nombor yang mengandungi titik perpuluhan:
corak: \d*\.\d+ 
rentetan:   0.011 .2 42 2.0 3.33 4.000 5 6 7.89012 
padanan: ^^^^^ ^^ ^^^ ^^^^ ^^^^^ ^^^^^^^  
( Contoh ) Notabahawa dengan menjadikan nombor di sebelah kiri titik perpuluhan pilihan, kami dapat mencari kedua-dua 0.011 dan .2. Untuk melakukan ini, kami perlu memadankan tepat satu titik perpuluhan dengan \.dan sekurang-kurangnya satu digit di sebelah kanan titik perpuluhan dengan \d+. Ungkapan biasa di atas tidak akan sepadan dengan nombor seperti 3., kerana kita memerlukan sekurang-kurangnya satu digit di sebelah kanan titik perpuluhan untuk dipadankan.

Seperti biasa, mari selesaikan beberapa masalah mudah:

Cari semua perkataan Inggeris dalam petikan di bawah.
corak:
rentetan: 3 tambah 3 ialah enam tetapi 4 tambah tiga ialah 7
padanan:    ^^^^ ^^ ^^^ ^^^ ^^^^ ^^^^^ ^^ 
( Penyelesaian ) Cari semua simbol saiz fail dalam senarai di bawah. Saiz fail akan terdiri daripada nombor (dengan atau tanpa titik perpuluhan) diikuti dengan KB, MB, GBatau TB:
corak:
rentetan:   11TB 13 14.4MB 22HB 9.9GB TB 0KB 
padanan: ^^^^ ^^^^^^ ^^^^^ ^^^  
( Penyelesaian )

Langkah 9: tanda soal "pilihan".?

RegEx: 20 langkah pendek untuk menguasai ungkapan biasa.  Bahagian 2 - 3Adakah anda sudah menulis regex untuk menyelesaikan masalah terakhir? Adakah ia berhasil? Sekarang cuba gunakannya di sini:
corak:
rentetan: 1..3KB 5...GB ..6TB
perlawanan:  
Jelas sekali, kedua-dua sebutan ini bukan saiz fail yang sah, jadi ungkapan biasa yang baik tidak sepatutnya sepadan dengan salah satu daripadanya. Penyelesaian yang saya tulis untuk menyelesaikan masalah terakhir sepadan dengan mereka semua, sekurang-kurangnya sebahagiannya:
corak: \d+\.*\d*[KMGT]B 
rentetan:   1..3KB  5...GB .. padanan 6TB 
: ^^^^^^ ^^^^^^ ^^^ 
( Contoh ) Jadi apa masalahnya? Sebenarnya, kita hanya perlu mencari satu titik perpuluhan, jika ada. Tetapi *ia membenarkan sebarang bilangan padanan, termasuk sifar. Adakah terdapat cara untuk memadankan hanya sifar kali atau sekali? Tetapi tidak lebih daripada sekali? Sudah tentu ada. "pilihan" ?ialah pengubah suai yang sepadan dengan sifar atau salah satu aksara sebelumnya, tetapi tidak lebih:
corak: \d+\.?\d*[KMGT]B 
rentetan: 1.. 3KB 5...GB .. 
padanan     6TB : ^^^ ^^^ 
( Contoh ) Kami lebih hampir kepada penyelesaian di sini, tetapi ini bukan perkara yang kami perlukan. Kita akan lihat cara membetulkannya dalam beberapa langkah sedikit kemudian.

Sementara itu, mari kita selesaikan masalah ini:

Dalam sesetengah bahasa pengaturcaraan (cth. Java), beberapa nombor integer dan titik terapung (titik) boleh diikuti dengan l/ Ldan f/ Funtuk menunjukkan bahawa mereka harus dianggap sebagai long/float (masing-masing) dan bukannya sebagai int/double biasa. Cari semua nombor "panjang" yang sah dalam baris di bawah:
corak:
rentetan:   13L panjang 2l 19 L lL 0 
padanan: ^^^ ^^ ^^ ^ 
( Penyelesaian )

Langkah 10: tanda "atau".|

RegEx: 20 langkah pendek untuk menguasai ungkapan biasa.  Bahagian 2 - 4Dalam langkah 8, kami mengalami sedikit kesukaran mencari pelbagai jenis nombor titik terapung:
corak: \d*\.\d+ 
rentetan:   0.011 .2 42 2.0 3.33 4.000 5 6 7.89012 
padanan: ^^^^^ ^^ ^^^ ^^^^ ^^^^^ ^^^^^^^  
Corak di atas memadankan nombor dengan titik perpuluhan dan sekurang-kurangnya satu digit di sebelah kanan titik perpuluhan. Tetapi bagaimana jika kita juga mahu memadankan rentetan seperti 0.? (Tiada nombor di sebelah kanan titik perpuluhan.) Kita boleh menulis ungkapan biasa seperti ini:
corak: \d*\.\d* 
rentetan:   0.011 .2 42 2.0 3.33 4.000 5 6 7.89012 0. . 
perlawanan: ^^^^^ ^^ ^^^ ^^^^ ^^^^^ ^^^^^^^ ^^ ^ 
( Contoh ) Ini sepadan 0., tetapi ia juga sepadan dengan satu mata ., seperti yang anda boleh lihat di atas. Sebenarnya apa yang kami cuba padankan ialah dua kelas rentetan yang berbeza:
  1. nombor dengan sekurang-kurangnya satu digit di sebelah kanan titik perpuluhan
  2. nombor dengan sekurang-kurangnya satu digit di sebelah kiri titik perpuluhan
Mari kita tulis 2 ungkapan biasa berikut, bebas antara satu sama lain:
corak: \d*\.\d+ 
rentetan:   0.011 .2 42 2.0 3.33 4.000 5 6 7.89012 0. .
perlawanan: ^^^^^ ^^ ^^^ ^^^^ ^^^^^ ^^^^^^^  
corak: \d+\.\d* 
rentetan:   0.011 .2 42 2.0 3.33 4.000 5 6 7.89012 0. .
perlawanan: ^^^^^ ^^^ ^^^^ ^^^^^ ^^^^^^^ ^^ 
Kami melihat bahawa dalam mana-mana kes ini subrentetan 42, 5, 6atau .ditemui oleh enjin. Untuk mendapatkan hasil yang diperlukan, tidak ada salahnya kami menggabungkan ungkapan biasa ini. Bagaimanakah kita boleh mencapai ini? Tanda "atau" |membolehkan kami menentukan beberapa kemungkinan urutan padanan sekaligus dalam ungkapan biasa. Sama seperti []tanda "atau" membolehkan kami menentukan aksara tunggal alternatif, |kami boleh menentukan ungkapan berbilang aksara alternatif. Contohnya, jika kita ingin mencari "anjing" atau "kucing", kita boleh menulis sesuatu seperti ini:
corak: \w\w\w 
rentetan:   Jelas sekali , anjing adalah haiwan peliharaan yang lebih baik daripada kucing .
perlawanan: ^^^^^^^^^ ^^^ ^^^^^^ ^^^ ^^^ ^^^ 
( Contoh ) ... tetapi ini sepadan dengan semua jujukan tiga aksara "perkataan" kelas. Tetapi "anjing" dan "kucing" tidak mempunyai huruf yang sama, jadi kurungan persegi tidak akan membantu kami di sini. Berikut ialah ungkapan biasa paling mudah yang boleh kami gunakan yang sepadan dengan kedua-duanya dan hanya dua perkataan ini:
corak: rentetan anjing|kucing 
: Jelas sekali, anjing adalah haiwan peliharaan yang lebih baik daripada kucing .
perlawanan:               ^^ ^^^ 
( Contoh ) Enjin ungkapan biasa mula-mula cuba memadankan keseluruhan jujukan di sebelah kiri aksara |, tetapi jika gagal, ia kemudiannya cuba memadankan jujukan di sebelah kanan aksara |. Berbilang aksara |juga boleh dirantai untuk memadankan lebih daripada dua urutan alternatif:
corak: anjing|kucing| 
rentetan haiwan peliharaan: Jelas sekali, anjing adalah haiwan peliharaan yang lebih baik daripada kucing .
perlawanan:               ^^^ ^^^ ^^^ 
( Contoh )

Sekarang mari kita selesaikan beberapa masalah lain untuk lebih memahami langkah ini:

Gunakan tanda |untuk membetulkan ungkapan biasa perpuluhan di atas untuk menghasilkan keputusan seperti ini:
corak:
rentetan:   0.011 .2 42 2.0 3.33 4.000 5 6 7.89012 0. .
perlawanan: ^^^^^ ^^ ^^^ ^^^^ ^^^^^ ^^^^^^^ ^^ 
( Penyelesaian ) Gunakan tanda |, kelas aksara, "pilihan" ?, dsb. untuk mencipta satu ungkapan biasa yang sepadan dengan kedua-dua nombor integer dan titik terapung (titik), seperti yang dibincangkan dalam masalah pada penghujung langkah sebelumnya (masalah ini sedikit lebih rumit, ya ;))
corak:
rentetan:   42L 12 x 3.4f 6l 3.3 0F LF .2F 0. 
padanan: ^^^ ^^ ^^^^ ^^ ^^^ ^^ ^^^ ^^  
( Penyelesaian ) 20 langkah pendek untuk menguasai ungkapan biasa. Bahagian 3 RegEx: 20 langkah pendek untuk menguasai ungkapan biasa. Bahagian 4
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION