JavaRush /Blog Java /Random-MS /Ungkapan Biasa di Jawa, Bahagian 3

Ungkapan Biasa di Jawa, Bahagian 3

Diterbitkan dalam kumpulan
Kami menyampaikan kepada perhatian anda terjemahan panduan ringkas kepada ungkapan biasa dalam Java, yang ditulis oleh Jeff Friesen untuk tapak web javaworld . Untuk memudahkan pembacaan, kami telah membahagikan artikel tersebut kepada beberapa bahagian. Ungkapan Biasa di Jawa, Bahagian 3 - 1Ungkapan Biasa di Jawa, Bahagian 1 Ungkapan Biasa di Jawa, Bahagian 2

Permudahkan tugas pengaturcaraan biasa dengan Regex API

Dalam Bahagian 1 dan 2 artikel ini, anda telah diperkenalkan kepada ungkapan biasa dan API Regex. Anda mempelajari tentang kelas Patterndan menelusuri contoh yang menunjukkan binaan ungkapan biasa, daripada padanan corak mudah menggunakan rentetan literal kepada padanan yang lebih kompleks menggunakan julat, pemadan sempadan dan pengkuantiti. Dalam bahagian ini dan seterusnya kami akan mempertimbangkan isu yang tidak diliputi dalam bahagian pertama, kami akan mengkaji kaedah kelas yang sepadan Pattern, Matcherdan PatternSyntaxException. Anda juga akan mempelajari dua utiliti yang menggunakan ungkapan biasa untuk memudahkan masalah pengaturcaraan biasa. Yang pertama mengekstrak komen daripada kod untuk dokumentasi. Yang kedua ialah perpustakaan kod boleh guna semula yang direka untuk melaksanakan analisis leksikal - komponen penting pemasang, penyusun, dan perisian yang serupa.

MUAT TURUN KOD SUMBER

Anda boleh mendapatkan semua kod sumber (dicipta oleh Jeff Friesen untuk JavaWorld) untuk aplikasi demo dalam artikel ini dari sini .

Mempelajari API Regex

Pattern, Matcherdan PatternSyntaxExceptionmerupakan tiga kelas yang membentuk API Regex. Setiap daripada mereka menyediakan kaedah yang membolehkan anda menggunakan ungkapan biasa dalam kod anda.

Kaedah kelas Corak

Contoh kelas Patternialah ungkapan biasa yang disusun, juga dikenali sebagai corak. Ungkapan biasa disusun untuk meningkatkan prestasi operasi padanan corak. Kaedah statik berikut menyokong kompilasi.
  • Pattern compile(String regex)menyusun kandungan regexmenjadi perwakilan perantaraan yang disimpan dalam Pattern. Kaedah ini sama ada mengembalikan rujukan kepada objek jika berjaya, atau membuang pengecualian PatternSyntaxExceptionjika sintaks ungkapan biasa yang tidak sah dikesan. Mana-mana objek kelas Matcheryang digunakan oleh Patternatau dikembalikan daripada objek ini menggunakan tetapan lalainya, seperti carian sensitif huruf besar-besaran. Sebagai contoh, coretan kod Pattern p = Pattern.compile("(?m)^\\."); mencipta objek Patternyang menyimpan perwakilan terkumpul ungkapan biasa untuk memadankan rentetan yang bermula dengan aksara titik.

  • Pattern compile(String regex, int flags)menyelesaikan masalah yang sama seperti Pattern compile(String regex), tetapi mengambil kira flags: satu set pemalar bit untuk bendera bit jenis OR. Kelas Patternmengisytiharkan pemalar CANON_EQ, CASE_INSENSITIVE, COMMENTS, DOTALL, LITERAL, MULTILINE, UNICODE_CASE, UNICODE_CHARACTER_CLASS и UNIX_LINESyang boleh digabungkan menggunakan bitwise OR (contohnya, CASE_INSENSITIVE | DOTALL) dan diluluskan sebagai argumen flags.

  • Dengan pengecualian CANON_EQ, LITERAL и UNICODE_CHARACTER_CLASS, pemalar ini adalah alternatif kepada ungkapan bendera bersarang yang ditunjukkan dalam Bahagian 1. Jika pemalar bendera selain daripada yang ditakrifkan dalam kelas ditemui Pattern, kaedah Pattern compile(String regex, int flags) membuang pengecualian java.lang.IllegalArgumentException. Sebagai contoh, Pattern p = Pattern.compile("^\\.", Pattern.MULTILINE);bersamaan dengan contoh sebelumnya, dengan pemalar Pattern.MULTILINEdan ungkapan bendera bersarang (?m)melakukan perkara yang sama.
Kadangkala adalah perlu untuk mendapatkan salinan rentetan asal ungkapan biasa yang disusun ke dalam objek Pattern, bersama-sama dengan bendera yang digunakannya. Untuk melakukan ini, anda boleh menghubungi kaedah berikut:
  • String pattern()mengembalikan rentetan ungkapan biasa asal yang disusun menjadi Pattern.

  • int flags()mengembalikan bendera objek Pattern.
Selepas menerima objek Pattern, ia biasanya digunakan untuk mendapatkan objek Matcheruntuk melaksanakan operasi padanan corak. Kaedah Matcher matcher(Charsequence input)mencipta objek Matcheryang mencari teks inputuntuk padanan dengan corak objek Pattern. Apabila dipanggil, ia mengembalikan rujukan kepada objek ini Matcher. Sebagai contoh, arahan Matcher m = p.matcher(args[1]);kembali Matcheruntuk objek Patternyang dirujuk oleh pembolehubah p.
Carian sekali sahaja
Kaedah static boolean matches(String regex, CharSequence input)kelas Patternmembolehkan anda menjimatkan membuat objek Patterndan Matchercarian sekali menggunakan templat. Kaedah ini mengembalikan benar jika inputcorak dipadankan regex, jika tidak ia mengembalikan palsu. Jika ungkapan biasa mengandungi ralat sintaks, kaedah membuang pengecualian PatternSyntaxException. Sebagai contoh, System.out.println(Pattern.matches("[a-z[\\s]]*", "all lowercase letters and whitespace only"));cetakan true, mengesahkan bahawa frasa all lowercase letters and whitespace onlyhanya mengandungi ruang dan aksara kecil.
Ungkapan Biasa dalam Java, Bahagian 3 - 2

Memisahkan teks

Kebanyakan pembangun mempunyai sekurang-kurangnya sekali kod bertulis untuk memecahkan teks input kepada bahagian komponennya, seperti menukar akaun pekerja berasaskan teks kepada satu set medan. Kelas Patternmenyediakan keupayaan untuk menyelesaikan tugas yang membosankan ini dengan lebih mudah menggunakan dua kaedah pemisahan teks:
  • Kaedah String[] split(CharSequence text, int limit)berpecah textmengikut padanan yang ditemui dengan corak objek Patterndan mengembalikan keputusan dalam tatasusunan. Setiap elemen tatasusunan menentukan urutan teks yang dipisahkan daripada urutan seterusnya oleh serpihan teks padanan corak (atau penghujung teks). Elemen tatasusunan berada dalam susunan yang sama di mana ia muncul dalam text.

    Dalam kaedah ini, bilangan elemen tatasusunan bergantung pada parameter limit, yang turut mengawal bilangan padanan yang akan ditemui.

    • Nilai positif mencari tidak lebih daripada limit-1padanan dan panjang tatasusunan tidak lebih daripada limitelemen.
    • Jika nilainya negatif, semua kemungkinan padanan akan dicari dan panjang tatasusunan boleh sewenang-wenangnya.
    • Jika nilainya adalah sifar, semua kemungkinan padanan dicari, panjang tatasusunan boleh sewenang-wenangnya dan baris kosong pada penghujungnya dibuang.

  • Kaedah String[] split(CharSequence text)memanggil kaedah sebelumnya dengan 0 sebagai hujah had dan mengembalikan hasil panggilannya.
Berikut adalah keputusan kaedah split(CharSequence text)untuk menyelesaikan masalah pembahagian akaun pekerja ke dalam bidang nama, umur, alamat pos dan gaji yang berasingan:
Pattern p = Pattern.compile(",\\s");
String[] fields = p.split("John Doe, 47, Hillsboro Road, 32000");
for (int i = 0; i < fields.length; i++)
   System.out.println(fields[i]);
Kod di atas menerangkan ungkapan biasa untuk mencari aksara koma serta-merta diikuti oleh aksara ruang tunggal. Berikut adalah hasil pelaksanaannya:
John Doe
47
Hillsboro Road
32000

Predikat templat dan API Strim

Dalam Java 8, Patternkaedah muncul dalam kelas . Kaedah ini mencipta predikat (fungsi dengan nilai boolean) yang digunakan untuk memadankan corak. Penggunaan kaedah ini ditunjukkan dalam coretan kod berikut: Predicate asPredicate()
List progLangs = Arrays.asList("apl", "basic", "c", "c++", "c#", "cobol", "java", "javascript", "perl", "python", "scala");
Pattern p = Pattern.compile("^c");
progLangs.stream().filter(p.asPredicate()).forEach(System.out::println);
Kod ini mencipta senarai nama bahasa pengaturcaraan, kemudian menyusun corak untuk mencari semua nama yang bermula dengan huruf c. Baris terakhir kod di atas melaksanakan penerimaan aliran data bersiri dengan senarai ini sebagai sumber. Ia menyediakan penapis menggunakan fungsi Boolean asPredicate()yang mengembalikan benar apabila nama itu bermula dengan huruf cdan berulang melalui strim, mencetak nama yang sepadan dengan output standard. Baris terakhir ini bersamaan dengan gelung biasa berikut, biasa daripada aplikasi RegexDemo dari Bahagian 1:
for (String progLang: progLangs)
   if (p.matcher(progLang).find())
      System.out.println(progLang);

Kaedah kelas matcher

Contoh kelas Matchermenerangkan mekanisme untuk melaksanakan operasi padanan corak pada jujukan aksara dengan mentafsir ungkapan biasa terkumpul kelas Pattern. Objek kelas Matchermenyokong pelbagai jenis operasi carian corak:
  • Kaedah boolean find()mencari teks input untuk padanan seterusnya. Kaedah ini mula mengimbas sama ada pada permulaan teks yang ditentukan atau pada aksara pertama selepas padanan sebelumnya. Pilihan kedua hanya boleh dilakukan jika panggilan sebelumnya kepada kaedah ini dikembalikan benar dan penyelesai tidak ditetapkan semula. Walau apa pun, jika carian berjaya, nilai boolean true dikembalikan. Contoh kaedah ini boleh didapati di RegexDemoBahagian 1.

  • Kaedah ini boolean find(int start)menetapkan semula padanan dan mencari teks untuk padanan seterusnya. Melihat bermula dari kedudukan yang ditentukan oleh parameter start. Jika carian berjaya, nilai boolean benar dikembalikan. Contohnya, m.find(1);mengimbas teks bermula dari kedudukan 1(kedudukan 0 diabaikan). Jika parameter startmengandungi nilai negatif atau nilai yang lebih besar daripada panjang teks pemadan, kaedah itu membuang pengecualian java.lang.IndexOutOfBoundsException.

  • Kaedah ini boolean matches()cuba memadankan semua teks dengan corak. Ia mengembalikan nilai boolean benar jika semua teks sepadan dengan corak. Sebagai contoh, kod Pattern p = Pattern.compile("\\w*"); Matcher m = p.matcher("abc!"); System.out.println(p.matches());keluar falsekerana watak itu !bukan aksara perkataan.

  • Kaedah ini boolean lookingAt()cuba memadankan teks yang diberikan dengan corak. Kaedah ini kembali benar jika mana-mana bahagian teks sepadan dengan corak. Tidak seperti kaedah matches();, semua teks tidak perlu sepadan dengan corak. Sebagai contoh, Pattern p = Pattern.compile("\\w*"); Matcher m = p.matcher("abc!"); System.out.println(p.lookingAt());ia akan mengeluarkan true, kerana permulaan teks abc!hanya terdiri daripada aksara pembentuk perkataan.

Tidak seperti objek kelas Pattern, objek kelas Matchermengekalkan maklumat keadaan. Kadangkala anda mungkin perlu menetapkan semula pemadan untuk mengosongkan maklumat ini selepas carian corak selesai. Kaedah berikut tersedia untuk menetapkan semula penyelesai:
  • Kaedah ini Matcher reset()menetapkan semula keadaan pemadan, termasuk kedudukan yang akan dilampirkan pada penghujung (set semula kepada 0). Operasi carian corak seterusnya bermula pada permulaan teks pemadan. Mengembalikan rujukan kepada objek semasa Matcher. Sebagai contoh, m.reset();menetapkan semula penyelesai yang dirujuk oleh m.

  • Kaedah ini Matcher reset(CharSequence text)menetapkan semula keadaan penyelesai dan menetapkan teks penyelesai baharu kepada text. Operasi carian corak seterusnya bermula pada permulaan teks pemadanan baharu. Rujukan kepada objek semasa dikembalikan Matcher. Contohnya, m.reset("new text");menetapkan semula penyelesai yang dirujuk mdan menetapkan teks penyelesai baharu kepada "new text".

Ungkapan Biasa di Jawa, Bahagian 3 - 3

Menambah teks ke penghujung

Kedudukan pemadan yang hendak dilampirkan pada penghujung menentukan permulaan teks pemadan yang dilampirkan pada penghujung objek jenis java.lang.StringBuffer. Kaedah berikut menggunakan kedudukan ini:
  • Kaedah Matcher appendReplacement(StringBuffer sb, String replacement)membaca aksara teks pemadan dan menambahkannya pada penghujung objek StringBufferyang dirujuk oleh hujah sb. Kaedah ini berhenti membaca pada aksara terakhir sebelum padanan corak sebelumnya. Seterusnya, kaedah menambahkan aksara daripada objek jenis Stringyang dirujuk oleh hujah replacementke penghujung objek StringBuffer(rentetan replacementmungkin mengandungi rujukan kepada jujukan teks yang ditangkap semasa carian sebelumnya; ini ditentukan menggunakan aksara ($)dan nombor kumpulan yang ditangkap). Akhir sekali, kaedah menetapkan nilai kedudukan pemadan untuk ditambah pada kedudukan aksara dipadankan terakhir tambah satu, dan kemudian mengembalikan rujukan kepada pemadan semasa.

  • Kaedah Matcher appendReplacement(StringBuffer sb, String replacement)membuang pengecualian java.lang.IllegalStateExceptionjika pemadan belum menemui padanan atau percubaan carian sebelumnya gagal. Ia membuang pengecualian IndexOutOfBoundsExceptionjika garisan replacementmenentukan kumpulan tangkapan yang tiada dalam corak).

  • Kaedah ini StringBuffer appendTail(StringBuffer sb)menambah semua teks pada objek StringBufferdan mengembalikan rujukan kepada objek itu. Selepas panggilan kaedah terakhir appendReplacement(StringBuffer sb, String replacement), panggil kaedah appendTail(StringBuffer sb)untuk menyalin teks yang tinggal ke objek StringBuffer.

Kumpulan yang ditangkap
Seperti yang anda ingat dari Bahagian 1, kumpulan tangkapan ialah urutan aksara yang disertakan dalam kurungan ( ()) metakarakter. Tujuan konstruk ini adalah untuk menyimpan aksara yang ditemui untuk digunakan semula kemudian semasa padanan corak. Semua aksara daripada kumpulan yang ditangkap dianggap sebagai satu keseluruhan semasa pencarian corak.
Kod berikut memanggil kaedah appendReplacement(StringBuffer sb, String replacement)dan appendTail(StringBuffer sbuntuk menggantikan semua kemunculan jujukan aksara dalam teks sumber catdengan caterpillar:
Pattern p = Pattern.compile("(cat)");
Matcher m = p.matcher("one cat, two cats, or three cats on a fence");
StringBuffer sb = new StringBuffer();
while (m.find())
   m.appendReplacement(sb, "$1erpillar");
m.appendTail(sb);
System.out.println(sb);
Menggunakan kumpulan yang ditangkap dan rujukan kepadanya dalam teks gantian memberitahu program untuk memasukkan erpillarselepas setiap kejadian cat. Hasil daripada melaksanakan kod ini kelihatan seperti ini: one caterpillar, two caterpillars, or three caterpillars on a fence

Menggantikan teks

Kelas Matchermemberikan kita dua kaedah untuk penggantian teks, pelengkap kepada appendReplacement(StringBuffer sb, String replacement). Menggunakan kaedah ini, anda boleh menggantikan sama ada kejadian pertama [teks yang diganti] atau semua kejadian:
  • Kaedah ini String replaceFirst(String replacement)menetapkan semula pemadan, mencipta objek baharu String, menyalin semua aksara teks pemadan (sehingga padanan pertama) ke rentetan ini, menambah aksara dari ke penghujungnya replacement, menyalin aksara yang tinggal ke rentetan dan mengembalikan objek String(rentetan replacementboleh mengandungi rujukan kepada yang ditangkap semasa urutan teks carian sebelumnya menggunakan simbol dolar dan nombor kumpulan yang ditangkap).

  • Kaedah ini String replaceAll(String replacement)beroperasi sama dengan kaedah String replaceFirst(String replacement), tetapi menggantikan replacementsemua padanan yang ditemui dengan aksara daripada rentetan.

Ungkapan biasa \s+mencari satu atau lebih aksara ruang putih dalam teks input. Di bawah, kami akan menggunakan ungkapan biasa ini dan memanggil kaedah replaceAll(String replacement)untuk mengalih keluar ruang pendua:
Pattern p = Pattern.compile("\\s+");
Matcher m = p.matcher("Удаляем      \t\t лишние пробелы.   ");
System.out.println(m.replaceAll(" "));
Berikut ialah keputusannya: Удаляем лишние пробелы. Ungkapan Biasa di Jawa, Bahagian 4 Ungkapan Biasa di Jawa, Bahagian 5
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION