Panduan untuk Melarikan Karakter di Java RegExps

1. Ikhtisar

API ekspresi reguler di Java, java.util.regex banyak digunakan untuk pencocokan pola. Untuk mengetahui lebih lanjut, Anda dapat mengikuti artikel ini.

Pada artikel ini, kami akan fokus pada karakter pelolosan dengan ekspresi reguler dan menunjukkan bagaimana hal itu dapat dilakukan di Java.

2. Karakter RegExp Khusus

Menurut dokumentasi API ekspresi reguler Java, terdapat sekumpulan karakter khusus yang juga dikenal sebagai karakter meta yang ada dalam ekspresi reguler.

Ketika kita ingin membiarkan karakter apa adanya alih-alih menafsirkannya dengan arti khusus mereka, kita perlu menghindarinya. Dengan meng-escape karakter ini, kami memaksanya untuk diperlakukan sebagai karakter biasa saat mencocokkan string dengan ekspresi reguler yang diberikan.

Karakter meta yang biasanya perlu kita hindari dengan cara ini adalah:

Mari kita lihat contoh kode sederhana di mana kita mencocokkan String input dengan pola yang diekspresikan dalam ekspresi reguler.

Tes ini menunjukkan bahwa untuk masukan string yang diberikan foof ketika pola foo . ( foo diakhiri dengan karakter titik) cocok, mengembalikan nilai true yang menunjukkan bahwa kecocokan berhasil.

@Test public void givenRegexWithDot_whenMatchingStr_thenMatches() { String strInput = "foof"; String strRegex = "foo."; assertEquals(true, strInput.matches(strRegex)); }

Anda mungkin bertanya-tanya mengapa kecocokan berhasil ketika tidak ada karakter titik (.) Yang ada dalam String input ?

Jawabannya sederhana. Titik (.) Adalah karakter meta - signifikansi khusus dari titik di sini adalah bahwa dapat ada 'karakter apa pun' di tempatnya. Oleh karena itu, jelas bagaimana matcher menentukan kecocokan ditemukan.

Katakanlah kita tidak ingin memperlakukan karakter titik (.) Dengan arti uniknya. Sebaliknya, kami ingin itu diartikan sebagai tanda titik. Artinya pada contoh sebelumnya, kita tidak ingin membiarkan pola foo. untuk mencocokkan di String input .

Bagaimana kita menangani situasi seperti ini? Jawabannya adalah: kita perlu menghindar dari karakter titik (.) Agar makna khususnya diabaikan.

Mari kita gali lebih detail di bagian selanjutnya.

3. Karakter yang Melarikan Diri

Menurut dokumentasi Java API untuk ekspresi reguler, ada dua cara di mana kita dapat melarikan diri dari karakter yang memiliki arti khusus. Dengan kata lain, memaksa mereka untuk diperlakukan sebagai karakter biasa.

Mari kita lihat apa itu:

  1. Awali karakter meta dengan garis miring terbalik (\)
  2. Lampirkan karakter meta dengan \ Q dan \ E

Ini hanya berarti bahwa pada contoh yang kita lihat sebelumnya, jika kita ingin melepaskan karakter titik, kita perlu meletakkan karakter garis miring terbalik sebelum karakter titik. Sebagai alternatif, kita dapat menempatkan karakter titik di antara \ Q dan \ E.

3.1. Escaping Menggunakan Backslash

Ini adalah salah satu teknik yang dapat kita gunakan untuk mengosongkan karakter meta dalam ekspresi reguler. Namun, kita tahu bahwa karakter garis miring terbalik adalah karakter pelarian dalam literal String Java juga. Oleh karena itu, kita perlu menggandakan karakter garis miring terbalik saat menggunakannya untuk mendahului karakter apa pun (termasuk karakter \ itu sendiri).

Karenanya dalam contoh kita, kita perlu mengubah ekspresi reguler seperti yang ditunjukkan dalam tes ini:

@Test public void givenRegexWithDotEsc_whenMatchingStr_thenNotMatching() { String strInput = "foof"; String strRegex = "foo\\."; assertEquals(false, strInput.matches(strRegex)); }

Di sini, karakter titik di-escape, jadi matcher hanya memperlakukannya sebagai titik dan mencoba menemukan pola yang diakhiri dengan titik (mis . Foo. ).

Dalam hal ini, mengembalikan nilai salah karena tidak ada kecocokan dalam string masukan untuk pola itu.

3.2. Escaping Menggunakan \ Q & \ E

Alternatifnya, kita dapat menggunakan \ Q dan \ E untuk keluar dari karakter khusus. \ Q menunjukkan bahwa semua karakter sampai dengan \ E perlu melarikan diri dan \ E berarti kita harus mengakhiri melarikan diri yang dimulai dengan \ Q .

Ini hanya berarti bahwa apapun yang berada di antara \ Q dan \ E akan di-escape.

Dalam pengujian yang ditampilkan di sini, split () dari kelas String melakukan kecocokan menggunakan ekspresi reguler yang disediakan untuknya.

Persyaratan kami adalah membagi string input dengan karakter pipa (|) menjadi kata-kata. Oleh karena itu, kami menggunakan pola ekspresi reguler untuk melakukannya.

Karakter pipa adalah karakter meta yang perlu di-escape dalam ekspresi reguler.

Di sini, escaping dilakukan dengan menempatkan karakter pipa antara \ Q dan \ E :

@Test public void givenRegexWithPipeEscaped_whenSplitStr_thenSplits() \\E"; assertEquals(4, strInput.split(strRegex).length); 

4. Metode Pattern.quote (String S)

Metode Pattern.Quote (String S) di kelas java.util.regex.Pattern mengonversi String pola ekspresi reguler yang diberikan menjadi String pola literal . Ini berarti bahwa semua karakter meta dalam String input diperlakukan sebagai karakter biasa.

Menggunakan metode ini akan menjadi alternatif yang lebih nyaman daripada menggunakan \ Q & \ E karena metode ini membungkus String yang diberikan dengannya.

Mari kita lihat metode ini beraksi:

@Test public void givenRegexWithPipeEscQuoteMeth_whenSplitStr_thenSplits() bar

Dalam pengujian cepat ini, metode Pattern.quote () digunakan untuk keluar dari pola regex yang diberikan dan mengubahnya menjadi literal String . Dengan kata lain, ini lolos dari semua karakter meta yang ada dalam pola regex untuk kita. Ini adalah melakukan pekerjaan yang sama dengan \ Q & \ E .

Karakter pipa diloloskan oleh metode Pattern.quote () dan split () menafsirkannya sebagai literal String yang membagi input.

Seperti yang bisa kita lihat, ini adalah pendekatan yang jauh lebih bersih dan juga pengembang tidak perlu mengingat semua urutan pelarian.

Kita harus mencatat bahwa Pattern.quote membungkus seluruh blok dengan satu urutan escape. Jika kita ingin melepaskan karakter satu per satu, kita perlu menggunakan algoritma penggantian token.

5. Contoh Tambahan

Mari kita lihat cara kerja metode replaceAll () java.util.regex.Matcher .

Jika kita perlu mengganti semua kemunculan karakter String yang diberikan dengan yang lain, kita dapat menggunakan metode ini dengan meneruskan ekspresi reguler padanya.

Bayangkan kita memiliki masukan dengan beberapa kemunculan karakter $ . Hasil yang ingin kita dapatkan adalah string yang sama dengan karakter $ diganti dengan £.

Tes ini mendemonstrasikan bagaimana pola $ diteruskan tanpa di-escape:

@Test public void givenRegexWithDollar_whenReplacing_thenNotReplace() { String strInput = "I gave $50 to my brother." + "He bought candy for $35. Now he has $15 left."; String strRegex = "$"; String strReplacement = "£"; String output = "I gave £50 to my brother." + "He bought candy for £35. Now he has £15 left."; Pattern p = Pattern.compile(strRegex); Matcher m = p.matcher(strInput); assertThat(output, not(equalTo(m.replaceAll(strReplacement)))); }

Tes menegaskan bahwa $ tidak diganti dengan benar oleh £ .

Sekarang jika kita keluar dari pola regex, penggantian terjadi dengan benar, dan tes berhasil seperti yang ditunjukkan dalam cuplikan kode ini:

@Test public void givenRegexWithDollarEsc_whenReplacing_thenReplace() { String strInput = "I gave $50 to my brother." + "He bought candy for $35. Now he has $15 left."; String strRegex = "\\$"; String strReplacement = "£"; String output = "I gave £50 to my brother." + "He bought candy for £35. Now he has £15 left."; Pattern p = Pattern.compile(strRegex); Matcher m = p.matcher(strInput); assertEquals(output,m.replaceAll(strReplacement)); }

Perhatikan \\ $ di sini, yang melakukan trik dengan mengosongkan karakter $ dan berhasil mencocokkan polanya.

6. Kesimpulan

Dalam artikel ini, kami melihat karakter yang keluar dalam ekspresi reguler di Java.

Kami membahas mengapa ekspresi reguler perlu di-escape, dan berbagai cara untuk mencapainya.

Seperti biasa, kode sumber yang terkait dengan artikel ini dapat ditemukan di GitHub.