CodeGym /Java Blog /Acak /Ekspresi reguler di Jawa
John Squirrels
Level 41
San Francisco

Ekspresi reguler di Jawa

Dipublikasikan di grup Acak
Ekspresi reguler adalah topik yang sering ditunda oleh programmer, bahkan yang berpengalaman. Tetapi cepat atau lambat, sebagian besar pengembang Java harus memproses informasi tekstual. Paling sering, ini berarti mencari dan mengedit teks. Tanpa ekspresi reguler, kode pemrosesan teks yang efektif dan ringkas tidak terpikirkan. Jadi berhentilah menunda-nunda, mari kita tangani ekspresi reguler sekarang. Ini tidak begitu sulit. Ekspresi reguler di Jawa - 1

Apa itu ekspresi reguler (regex)?

Faktanya, ekspresi reguler adalah pola untuk menemukan string dalam teks. Di Java, representasi asli dari pola ini selalu berupa string, yaitu objek dari kelas String. Namun, bukan sembarang string yang dapat dikompilasi menjadi ekspresi reguler — hanya string yang sesuai dengan aturan untuk membuat ekspresi reguler. Sintaks didefinisikan dalam spesifikasi bahasa. Ekspresi reguler ditulis menggunakan huruf dan angka, serta karakter meta, yaitu karakter yang memiliki arti khusus dalam sintaksis ekspresi reguler. Misalnya:

String regex = "java"; // The pattern is "java";
String regex = "\\d{3}"; // The pattern is three digits;

Membuat ekspresi reguler di Jawa

Membuat ekspresi reguler di Java melibatkan dua langkah sederhana:
  1. tulis sebagai string yang sesuai dengan sintaks ekspresi reguler;
  2. kompilasi string menjadi ekspresi reguler;
Dalam program Java apa pun, kami mulai bekerja dengan ekspresi reguler dengan membuat Patternobjek. Untuk melakukannya, kita perlu memanggil salah satu dari dua metode statis kelas: compile. Metode pertama mengambil satu argumen — string literal yang berisi ekspresi reguler, sedangkan yang kedua mengambil argumen tambahan yang menentukan pengaturan pencocokan pola:

public static Pattern compile (String literal)
public static Pattern compile (String literal, int flags)
Daftar nilai potensial dari flagsparameter didefinisikan di Patternkelas dan tersedia untuk kita sebagai variabel kelas statis. Misalnya:

Pattern pattern = Pattern.compile("java", Pattern.CASE_INSENSITIVE); // Pattern-matching will be case insensitive.
Pada dasarnya, Patternkelas adalah konstruktor untuk ekspresi reguler. Di balik layar, compilemetode ini memanggil Patternkonstruktor privat kelas untuk membuat representasi terkompilasi. Mekanisme pembuatan objek ini diimplementasikan dengan cara ini untuk membuat objek yang tidak dapat diubah. Saat ekspresi reguler dibuat, sintaksnya diperiksa. Jika string berisi kesalahan, maka PatternSyntaxExceptiondihasilkan a.

Sintaks ekspresi reguler

Sintaks ekspresi reguler bergantung pada <([{\^-=$!|]})?*+.>karakter, yang dapat digabungkan dengan huruf. Tergantung pada perannya, mereka dapat dibagi menjadi beberapa kelompok:
1. Metakarakter untuk mencocokkan batas garis atau teks
Metakarakter Keterangan
^ awal dari sebuah baris
$ akhir baris
\B batas kata
\B batas bukan kata
\A awal masukan
\G akhir pertandingan sebelumnya
\Z akhir masukan
\z akhir masukan
2. Karakter meta untuk mencocokkan kelas karakter yang telah ditentukan sebelumnya
Metakarakter Keterangan
\D angka
\D non-digit
\S karakter spasi putih
\S karakter bukan spasi
\w karakter alfanumerik atau garis bawah
\W karakter apa pun kecuali huruf, angka, dan garis bawah
. karakter apapun
3. Metakarakter untuk mencocokkan karakter kontrol
Metakarakter Keterangan
\T karakter tab
\N karakter baris baru
\R Kereta kembali
\F karakter umpan baris
\u0085 karakter baris berikutnya
\u2028 pemisah garis
\u2029 pemisah paragraf
4. Metakarakter untuk kelas karakter
Metakarakter Keterangan
[abc] salah satu karakter yang terdaftar (a, b, atau c)
[^abc] karakter apa pun selain yang terdaftar (bukan a, b, atau c)
[a-zA-Z] rentang gabungan (karakter Latin dari a hingga z, tidak peka huruf besar/kecil)
[iklan[mp]] penyatuan karakter (dari a ke d dan dari m ke p)
[az&&[def]] persimpangan karakter (d, e, f)
[az&&[^bc]] pengurangan karakter (a, dz)
5. Metacharacters untuk menunjukkan jumlah karakter (quantifiers). Kuantor selalu didahului oleh karakter atau grup karakter.
Metakarakter Keterangan
? satu atau tidak sama sekali
* nol kali atau lebih
+ satu kali atau lebih
{N} n kali
{N,} n kali atau lebih
{n,m} minimal n kali dan tidak lebih dari m kali

Kuantifikasi serakah

Satu hal yang harus Anda ketahui tentang bilangan adalah bahwa mereka datang dalam tiga varietas berbeda: serakah, posesif, dan enggan. Anda membuat quantifier posesif dengan menambahkan +karakter " " setelah quantifier. Anda membuatnya enggan dengan menambahkan " ?". Misalnya:

"A.+a" // greedy
"A.++a" // possessive
"A.+?a" // reluctant
Mari coba gunakan pola ini untuk memahami cara kerja berbagai jenis bilangan. Secara default, quantifier serakah. Ini berarti mereka mencari kecocokan terpanjang dalam string. Jika kita menjalankan kode berikut:

public static void main(String[] args) {
    String text = "Fred Anna Alexander";
    Pattern pattern = Pattern.compile("A.+a");
    Matcher matcher = pattern.matcher(text);
    while (matcher.find()) {
        System.out.println(text.substring(matcher.start(), matcher.end()));
    }
}
kita mendapatkan output ini:

Anna Alexa
Untuk ekspresi reguler " A.+a", pencocokan pola dilakukan sebagai berikut:
  1. Karakter pertama dalam pola yang ditentukan adalah huruf Latin A. Matchermembandingkannya dengan setiap karakter teks, dimulai dari indeks nol. Karakter Fberada pada indeks nol dalam teks kita, jadi Matcherulangi melalui karakter hingga cocok dengan polanya. Dalam contoh kita, karakter ini ditemukan di indeks 5.

    Ekspresi reguler di Jawa - 2
  2. Setelah ditemukan kecocokan dengan karakter pertama pola, Matchercari kecocokan dengan karakter keduanya. Dalam kasus kami, ini adalah .karakter " ", yang merupakan singkatan dari karakter apa pun.

    Ekspresi reguler di Jawa - 3

    Karakter tersebut nberada di posisi keenam. Itu pasti memenuhi syarat sebagai kecocokan untuk "karakter apa pun".

  3. Matcherhasil untuk memeriksa karakter berikutnya dari pola. Dalam pola kami, ini disertakan dalam pembilang yang berlaku untuk karakter sebelumnya: " .+". Karena jumlah pengulangan "karakter apa saja" dalam pola kita adalah satu kali atau lebih, Matcherberulang kali mengambil karakter berikutnya dari string dan memeriksanya dengan pola selama cocok dengan "karakter apa saja". Dalam contoh kita — hingga akhir string (dari indeks 7 hingga indeks 18).

    Ekspresi reguler di Jawa - 4

    Pada dasarnya, Matchermelahap string sampai akhir — inilah tepatnya yang dimaksud dengan "rakus".

  4. Setelah Matcher mencapai akhir teks dan menyelesaikan pemeriksaan bagian " A.+" dari pola, ia mulai memeriksa sisa pola: a. Tidak ada lagi teks yang akan diteruskan, jadi pemeriksaan dilanjutkan dengan "mundur", mulai dari karakter terakhir:

    Ekspresi reguler di Jawa - 5
  5. Matcher"mengingat" jumlah pengulangan di .+bagian " " dari pola. Pada titik ini, ini mengurangi jumlah pengulangan satu per satu dan memeriksa pola yang lebih besar terhadap teks sampai ditemukan kecocokan:

    Ekspresi reguler di Jawa - 6

Penghitung posesif

Pengukur posesif sangat mirip dengan yang serakah. Perbedaannya adalah ketika teks telah ditangkap hingga akhir string, tidak ada pencocokan pola saat "mundur". Dengan kata lain, tiga tahap pertama sama dengan untuk bilangan rakus. Setelah menangkap seluruh string, pencocokan menambahkan sisa pola ke apa yang sedang dipertimbangkan dan membandingkannya dengan string yang ditangkap. Dalam contoh kita, menggunakan ekspresi reguler " A.++a", metode main tidak menemukan kecocokan. Ekspresi reguler di Jawa - 7

Kuantor enggan

  1. Untuk penjumlahan ini, seperti dengan variasi serakah, kode mencari kecocokan berdasarkan karakter pertama dari pola:

    Ekspresi reguler di Jawa - 8
  2. Kemudian mencari kecocokan dengan karakter berikutnya dari pola (karakter apa saja):

    Ekspresi reguler di Jawa - 9
  3. Tidak seperti pencocokan pola serakah, pencocokan terpendek dicari dalam pencocokan pola enggan. Ini berarti setelah menemukan kecocokan dengan karakter kedua pola (titik, yang sesuai dengan karakter di posisi 6 dalam teks, Matcherperiksa apakah teks cocok dengan sisa pola — karakter " a"

    Ekspresi reguler di Jawa - 10
  4. Teks tidak cocok dengan pola (yaitu berisi karakter " n" pada indeks 7), jadi Matchertambahkan lebih banyak "karakter apa saja", karena pembilang menunjukkan satu atau lebih. Kemudian lagi membandingkan pola dengan teks di posisi 5 sampai 8:

    Ekspresi reguler di Jawa - 11
  5. Dalam kasus kami, kecocokan ditemukan, tetapi kami belum mencapai akhir teks. Oleh karena itu, pencocokan pola dimulai kembali dari posisi 9, yaitu karakter pertama pola dicari menggunakan algoritme serupa dan ini berulang hingga akhir teks.

    Ekspresi reguler di Jawa - 12
Oleh karena itu, mainmetode memperoleh hasil sebagai berikut saat menggunakan pola " A.+?a": Anna Alexa Seperti yang dapat Anda lihat dari contoh kami, jenis pembilang yang berbeda menghasilkan hasil yang berbeda untuk pola yang sama. Jadi ingatlah ini dan pilih variasi yang tepat berdasarkan apa yang Anda cari.

Melarikan diri dari karakter dalam ekspresi reguler

Karena regular expression di Java, atau representasi aslinya, adalah string literal, kita perlu memperhitungkan aturan Java terkait string literal. Secara khusus, karakter garis miring terbalik " \" dalam literal string dalam kode sumber Java diinterpretasikan sebagai karakter kontrol yang memberi tahu kompiler bahwa karakter berikutnya adalah spesial dan harus diinterpretasikan dengan cara khusus. Misalnya:

String s = "The root directory is \nWindows"; // Move "Windows" to a new line
String s = "The root directory is \u00A7Windows"; // Insert a paragraph symbol before "Windows"
Ini berarti literal string yang menjelaskan ekspresi reguler dan menggunakan \karakter " " (yaitu untuk menunjukkan karakter meta) harus mengulangi garis miring terbalik untuk memastikan bahwa kompiler bytecode Java tidak salah menafsirkan string. Misalnya:

String regex = "\\s"; // Pattern for matching a whitespace character
String regex = "\"Windows\"";  // Pattern for matching "Windows"
Garis miring terbalik ganda juga harus digunakan untuk keluar dari karakter khusus yang ingin kita gunakan sebagai karakter "normal". Misalnya:

String regex = "How\\?";  // Pattern for matching "How?"

Metode kelas Pola

Kelas Patternmemiliki metode lain untuk bekerja dengan ekspresi reguler:
  • String pattern()‒ mengembalikan representasi string asli ekspresi reguler yang digunakan untuk membuat Patternobjek:

    
    Pattern pattern = Pattern.compile("abc");
    System.out.println(pattern.pattern()); // "abc"
    
  • static boolean matches(String regex, CharSequence input)– memungkinkan Anda memeriksa ekspresi reguler yang diteruskan sebagai regex terhadap teks yang diteruskan sebagai input. Pengembalian:

    benar – jika teks cocok dengan pola;
    salah – jika tidak;

    Misalnya:

    
    System.out.println(Pattern.matches("A.+a","Anna")); // true
    System.out.println(Pattern.matches("A.+a","Fred Anna Alexander")); // false
    
  • int flags()‒ mengembalikan nilai flagsset parameter pola saat pola dibuat atau 0 jika parameter tidak disetel. Misalnya:

    
    Pattern pattern = Pattern.compile("abc");
    System.out.println(pattern.flags()); // 0
    Pattern pattern = Pattern.compile("abc",Pattern.CASE_INSENSITIVE);
    System.out.println(pattern.flags()); // 2
    
  • String[] split(CharSequence text, int limit)- membagi teks yang diteruskan ke dalam Stringarray. Parameter limitmenunjukkan jumlah maksimum kecocokan yang dicari dalam teks:

    • jika limit > 0limit-1cocok;
    • jika limit < 0‒ semua cocok dalam teks
    • jika limit = 0‒ semua kecocokan dalam teks, string kosong di akhir larik akan dibuang;

    Misalnya:

    
    public static void main(String[] args) {
        String text = "Fred Anna Alexa";
        Pattern pattern = Pattern.compile("\\s");
        String[] strings = pattern.split(text,2);
        for (String s : strings) {
            System.out.println(s);
        }
        System.out.println("---------");
        String[] strings1 = pattern.split(text);
        for (String s : strings1) {
            System.out.println(s);
        }
    }
    

    Keluaran konsol:

    
    Fred
    Anna Alexa
    ---------
    Fred
    Anna
    Alexa
    

    Di bawah ini kita akan mempertimbangkan metode kelas lain yang digunakan untuk membuat Matcherobjek.

Metode kelas Matcher

Instance kelas Matcherdibuat untuk melakukan pencocokan pola. Matcheradalah "mesin pencari" untuk ekspresi reguler. Untuk melakukan pencarian, kita perlu memberikan dua hal: pola dan indeks awal. Untuk membuat Matcherobjek, Patternkelas menyediakan metode berikut: рublic Matcher matcher(CharSequence input) Metode mengambil urutan karakter, yang akan dicari. Ini adalah turunan dari kelas yang mengimplementasikan antarmuka CharSequence. Anda tidak hanya dapat melewati a String, tetapi juga a StringBuffer, StringBuilder, Segment, atau CharBuffer. Pola adalah Patternobjek tempat matchermetode dipanggil. Contoh membuat pencocokan:

Pattern p = Pattern.compile("a*b"); // Create a compiled representation of the regular expression
Matcher m = p.matcher("aaaaab"); // Create a "search engine" to search the text "aaaaab" for the pattern "a*b"
Sekarang kita dapat menggunakan "mesin pencari" kita untuk mencari kecocokan, mendapatkan posisi kecocokan dalam teks, dan mengganti teks menggunakan metode kelas. Metode boolean find()mencari kecocokan berikutnya dalam teks. Kita dapat menggunakan metode ini dan pernyataan loop untuk menganalisis seluruh teks sebagai bagian dari model peristiwa. Dengan kata lain, kita dapat melakukan operasi yang diperlukan saat suatu peristiwa terjadi, yaitu saat kita menemukan kecocokan dalam teks. Sebagai contoh, kita dapat menggunakan kelas int start()dan int end()metode ini untuk menentukan posisi kecocokan dalam teks. Dan kita dapat menggunakan metode String replaceFirst(String replacement)and String replaceAll(String replacement)untuk mengganti kecocokan dengan nilai parameter pengganti. Misalnya:

public static void main(String[] args) {
    String text = "Fred Anna Alexa";
    Pattern pattern = Pattern.compile("A.+?a");

    Matcher matcher = pattern.matcher(text);
    while (matcher.find()) {
        int start=matcher.start();
        int end=matcher.end();
        System.out.println("Match found: " + text.substring(start, end) + " from index "+ start + " through " + (end-1));
    }
    System.out.println(matcher.replaceFirst("Ira"));
    System.out.println(matcher.replaceAll("Mary"));
    System.out.println(text);
}
Keluaran:

Match found: Anna from index 5 through 8
Match found: Alexa from index 10 through 14
Fred Ira Alexa
Fred Mary Mary
Fred Anna Alexa
Contoh memperjelas bahwa metode replaceFirstdan replaceAllmembuat Stringobjek baru — sebuah string yang polanya cocok dengan teks asli digantikan oleh teks yang diteruskan ke metode sebagai argumen. Selain itu, replaceFirstmetode ini hanya menggantikan kecocokan pertama, tetapi replaceAllmetode ini menggantikan semua kecocokan dalam teks. Teks asli tetap tidak berubah. Operasi regex and class Patternyang Matcherpaling sering dibangun langsung ke dalam Stringclass. Ini adalah metode seperti split, matches, replaceFirst, dan replaceAll. Namun di balik layar, metode ini menggunakan kelas Patternand Matcher. Jadi jika Anda ingin mengganti teks atau membandingkan string dalam suatu program tanpa menulis kode tambahan apa pun, gunakan metode dariStringkelas. Jika Anda memerlukan fitur yang lebih canggih, ingat Patterndan Matcherkelas.

Kesimpulan

Dalam program Java, ekspresi reguler ditentukan oleh string yang mematuhi aturan pencocokan pola tertentu. Saat mengeksekusi kode, mesin Java mengkompilasi string ini menjadi Patternobjek dan menggunakan Matcherobjek untuk menemukan kecocokan dalam teks. Seperti yang saya katakan di awal, orang sering menunda ekspresi reguler untuk nanti, menganggapnya sebagai topik yang sulit. Tetapi jika Anda memahami sintaks dasar, karakter meta, dan pelolosan karakter, dan mempelajari contoh ekspresi reguler, Anda akan menemukan bahwa ekspresi reguler jauh lebih sederhana daripada yang terlihat pada pandangan pertama.

Lebih banyak membaca:

Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION