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 kelasPattern
dan 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
, Matcher
dan 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
, Matcher
dan PatternSyntaxException
merupakan tiga kelas yang membentuk API Regex. Setiap daripada mereka menyediakan kaedah yang membolehkan anda menggunakan ungkapan biasa dalam kod anda.
Kaedah kelas Corak
Contoh kelasPattern
ialah 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 kandunganregex
menjadi perwakilan perantaraan yang disimpan dalamPattern
. Kaedah ini sama ada mengembalikan rujukan kepada objek jika berjaya, atau membuang pengecualianPatternSyntaxException
jika sintaks ungkapan biasa yang tidak sah dikesan. Mana-mana objek kelasMatcher
yang digunakan olehPattern
atau dikembalikan daripada objek ini menggunakan tetapan lalainya, seperti carian sensitif huruf besar-besaran. Sebagai contoh, coretan kodPattern p = Pattern.compile("(?m)^\\.");
mencipta objekPattern
yang menyimpan perwakilan terkumpul ungkapan biasa untuk memadankan rentetan yang bermula dengan aksara titik.Pattern compile(String regex, int flags)
menyelesaikan masalah yang sama sepertiPattern compile(String regex)
, tetapi mengambil kiraflags
: satu set pemalar bit untuk bendera bit jenis OR. KelasPattern
mengisytiharkan pemalarCANON_EQ, CASE_INSENSITIVE, COMMENTS, DOTALL, LITERAL, MULTILINE, UNICODE_CASE, UNICODE_CHARACTER_CLASS и UNIX_LINES
yang boleh digabungkan menggunakan bitwise OR (contohnya,CASE_INSENSITIVE | DOTALL
) dan diluluskan sebagai argumenflags
.
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.MULTILINE
dan ungkapan bendera bersarang (?m)
melakukan perkara yang sama.
Pattern
, bersama-sama dengan bendera yang digunakannya. Untuk melakukan ini, anda boleh menghubungi kaedah berikut:
String pattern()
mengembalikan rentetan ungkapan biasa asal yang disusun menjadiPattern
.int flags()
mengembalikan bendera objekPattern
.
Pattern
, ia biasanya digunakan untuk mendapatkan objek Matcher
untuk melaksanakan operasi padanan corak. Kaedah Matcher matcher(Charsequence input)
mencipta objek Matcher
yang mencari teks input
untuk padanan dengan corak objek Pattern
. Apabila dipanggil, ia mengembalikan rujukan kepada objek ini Matcher
. Sebagai contoh, arahan Matcher m = p.matcher(args[1]);
kembali Matcher
untuk objek Pattern
yang dirujuk oleh pembolehubah p
.
Carian sekali sahaja |
---|
Kaedah static boolean matches(String regex, CharSequence input) kelas Pattern membolehkan anda menjimatkan membuat objek Pattern dan Matcher carian sekali menggunakan templat. Kaedah ini mengembalikan benar jika input corak 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 only hanya mengandungi ruang dan aksara kecil. |
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. KelasPattern
menyediakan keupayaan untuk menyelesaikan tugas yang membosankan ini dengan lebih mudah menggunakan dua kaedah pemisahan teks:
-
Kaedah
String[] split(CharSequence text, int limit)
berpecahtext
mengikut padanan yang ditemui dengan corak objekPattern
dan 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 dalamtext
.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-1
padanan dan panjang tatasusunan tidak lebih daripadalimit
elemen. - 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.
- Nilai positif mencari tidak lebih daripada
- Kaedah
String[] split(CharSequence text)
memanggil kaedah sebelumnya dengan 0 sebagai hujah had dan mengembalikan hasil panggilannya.
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,Pattern
kaedah 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 c
dan 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 kelasMatcher
menerangkan mekanisme untuk melaksanakan operasi padanan corak pada jujukan aksara dengan mentafsir ungkapan biasa terkumpul kelas Pattern
. Objek kelas Matcher
menyokong 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 diRegexDemo
Bahagian 1. -
Kaedah ini
boolean find(int start)
menetapkan semula padanan dan mencari teks untuk padanan seterusnya. Melihat bermula dari kedudukan yang ditentukan oleh parameterstart
. Jika carian berjaya, nilai boolean benar dikembalikan. Contohnya,m.find(1);
mengimbas teks bermula dari kedudukan1
(kedudukan 0 diabaikan). Jika parameterstart
mengandungi nilai negatif atau nilai yang lebih besar daripada panjang teks pemadan, kaedah itu membuang pengecualianjava.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, kodPattern p = Pattern.compile("\\w*"); Matcher m = p.matcher("abc!"); System.out.println(p.matches());
keluarfalse
kerana 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 kaedahmatches();
, 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 mengeluarkantrue
, kerana permulaan teksabc!
hanya terdiri daripada aksara pembentuk perkataan.
Pattern
, objek kelas Matcher
mengekalkan 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 semasaMatcher
. Sebagai contoh,m.reset();
menetapkan semula penyelesai yang dirujuk olehm
. -
Kaedah ini
Matcher reset(CharSequence text)
menetapkan semula keadaan penyelesai dan menetapkan teks penyelesai baharu kepadatext
. Operasi carian corak seterusnya bermula pada permulaan teks pemadanan baharu. Rujukan kepada objek semasa dikembalikanMatcher
. Contohnya,m.reset("new text");
menetapkan semula penyelesai yang dirujukm
dan menetapkan teks penyelesai baharu kepada"new text"
.
Menambah teks ke penghujung
Kedudukan pemadan yang hendak dilampirkan pada penghujung menentukan permulaan teks pemadan yang dilampirkan pada penghujung objek jenisjava.lang.StringBuffer
. Kaedah berikut menggunakan kedudukan ini:
-
Kaedah
Matcher appendReplacement(StringBuffer sb, String replacement)
membaca aksara teks pemadan dan menambahkannya pada penghujung objekStringBuffer
yang dirujuk oleh hujahsb
. Kaedah ini berhenti membaca pada aksara terakhir sebelum padanan corak sebelumnya. Seterusnya, kaedah menambahkan aksara daripada objek jenisString
yang dirujuk oleh hujahreplacement
ke penghujung objekStringBuffer
(rentetanreplacement
mungkin 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 ini
StringBuffer appendTail(StringBuffer sb)
menambah semua teks pada objekStringBuffer
dan mengembalikan rujukan kepada objek itu. Selepas panggilan kaedah terakhirappendReplacement(StringBuffer sb, String replacement)
, panggil kaedahappendTail(StringBuffer sb)
untuk menyalin teks yang tinggal ke objekStringBuffer
.
Kaedah Matcher appendReplacement(StringBuffer sb, String replacement)
membuang pengecualian java.lang.IllegalStateException
jika pemadan belum menemui padanan atau percubaan carian sebelumnya gagal. Ia membuang pengecualian IndexOutOfBoundsException
jika garisan replacement
menentukan kumpulan tangkapan yang tiada dalam corak).
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. |
appendReplacement(StringBuffer sb, String replacement)
dan appendTail(StringBuffer sb
untuk menggantikan semua kemunculan jujukan aksara dalam teks sumber cat
dengan 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 erpillar
selepas setiap kejadian cat
. Hasil daripada melaksanakan kod ini kelihatan seperti ini: one caterpillar, two caterpillars, or three caterpillars on a fence
Menggantikan teks
KelasMatcher
memberikan 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 baharuString
, menyalin semua aksara teks pemadan (sehingga padanan pertama) ke rentetan ini, menambah aksara dari ke penghujungnyareplacement
, menyalin aksara yang tinggal ke rentetan dan mengembalikan objekString
(rentetanreplacement
boleh 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 kaedahString replaceFirst(String replacement)
, tetapi menggantikanreplacement
semua padanan yang ditemui dengan aksara daripada rentetan.
\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
GO TO FULL VERSION