Mirip dengan utas kami untuk kiat golf khusus bahasa: apa saja trik umum untuk mempersingkat ekspresi reguler?
Saya dapat melihat tiga penggunaan regex ketika datang ke golf: golf regex klasik ("di sini adalah daftar yang harus cocok, dan di sini adalah daftar yang harus gagal"), menggunakan regex untuk memecahkan masalah komputasi dan ekspresi reguler yang digunakan sebagai bagian dari kode golf yang lebih besar. Jangan ragu untuk mengirim kiat mengatasi salah satu atau semua ini. Jika tip Anda terbatas pada satu atau lebih rasa, sebutkan rasa ini di atas.
Seperti biasa, harap tetap berpegang pada satu tip (atau keluarga tips yang sangat erat terkait) per jawaban, sehingga tips yang paling berguna dapat naik ke puncak melalui voting.
code-golf
tips
regular-expression
Martin Ender
sumber
sumber
Jawaban:
Kapan tidak melarikan diri
Aturan-aturan ini berlaku untuk sebagian besar rasa, jika tidak semua:
]
tidak perlu melarikan diri saat tidak cocok.{
dan}
tidak perlu melarikan diri ketika mereka bukan bagian dari pengulangan, misalnya{a}
pertandingan{a}
secara harfiah. Bahkan jika Anda ingin mencocokkan sesuatu seperti{2}
, Anda hanya perlu melarikan diri salah satunya, misalnya{2\}
.Di kelas karakter:
]
tidak perlu keluar ketika itu karakter pertama dalam set karakter, misalnya[]abc]
cocok dengan salah satu]abc
, atau ketika itu karakter kedua setelah a^
, misalnya[^]]
cocok dengan apa pun kecuali]
. (Pengecualian penting: rasa ECMAScript!)[
tidak perlu melarikan diri sama sekali. Bersama dengan tip di atas, ini berarti Anda bisa mencocokkan kedua tanda kurung dengan kelas karakter kontra-intuitif yang mengerikan[][]
.^
tidak perlu melarikan diri ketika itu bukan karakter pertama dalam rangkaian karakter, mis[ab^c]
.-
tidak perlu keluar ketika itu karakter pertama (kedua setelah a^
) atau terakhir dalam rangkaian karakter, misalnya[-abc]
,[^-abc]
atau[abc-]
.Tidak ada karakter lain yang perlu melarikan diri di dalam kelas karakter, bahkan jika mereka adalah karakter meta di luar kelas karakter (kecuali untuk backslash
\
itu sendiri).Juga, dalam beberapa rasa
^
dan$
dicocokkan secara harfiah ketika masing-masing tidak pada awal atau akhir regex.(Terima kasih kepada @ MartinBüttner karena telah mengisi beberapa detail)
sumber
[.]
). Melarikannya secara normal akan menghemat 1 byte dalam kasus ini\.
[
harus diloloskan di Jawa. Namun, tidak yakin tentang ICU (digunakan di Android dan iOS) atau .NET.Ekspresi reguler sederhana untuk mencocokkan semua karakter yang dapat dicetak dalam tabel ASCII .
sumber
Ketahui rasa regex Anda
Ada sejumlah orang yang berpikir bahwa ekspresi reguler pada dasarnya adalah agnostik bahasa. Namun, sebenarnya ada perbedaan yang cukup besar antara rasa, dan terutama untuk golf kode, ada baiknya untuk mengetahui beberapa di antaranya, dan fitur-fiturnya yang menarik, sehingga Anda dapat memilih yang terbaik untuk setiap tugas. Berikut ini adalah ikhtisar tentang beberapa rasa penting dan apa yang membedakan mereka dari yang lain. (Daftar ini tidak dapat benar-benar lengkap, tetapi beri tahu saya jika saya melewatkan sesuatu yang sangat mencolok.)
Perl dan PCRE
Saya melempar ini ke dalam panci tunggal, karena saya tidak terlalu terbiasa dengan rasa Perl dan kebanyakan setara (PCRE adalah untuk Ekspresi Reguler Kompatibel-Kompatibel setelah semua). Keuntungan utama dari rasa Perl adalah bahwa Anda benar-benar dapat memanggil kode Perl dari dalam regex dan substitusi.
(?(group)yes|no)
.\l
,\u
,\L
dan\U
.\G
untuk menambatkan pertandingan ke akhir pertandingan sebelumnya.\K
untuk mengatur ulang awal pertandingan\Q...\E
untuk menghindari lari karakter yang lebih lama. Berguna saat Anda mencoba mencocokkan string yang berisi banyak meta-karakter..BERSIH
Ini mungkin rasa yang paling kuat, dengan hanya sedikit kekurangan.
[\w-[aeiou]]
\d
adalah Unicode aware.Salah satu kekurangan penting dalam hal bermain golf adalah tidak mendukung quantifiers posesif seperti beberapa rasa lainnya. Alih-alih
.?+
Anda harus menulis(?>.?)
.Jawa
.*
dari mana Anda sekarang dapat memulai lookahead, seperti(?<=(?=lookahead).*)
.\Q...\E
seperti pada Perl / PCRE.Rubi
Dalam versi terbaru, rasa ini sama kuatnya dengan PCRE, termasuk dukungan untuk panggilan subrutin. Seperti Java, ini juga mendukung penyatuan dan persimpangan kelas karakter. Satu fitur khusus adalah kelas karakter bawaan untuk digit hex:
\h
(dan yang dinegasikan\H
).Fitur yang paling berguna untuk bermain golf adalah bagaimana Ruby menangani bilangan bulat. Terutama, dimungkinkan untuk mengukur sarang tanpa tanda kurung.
.{5,7}+
bekerja dan begitu juga.{3}?
. Juga, sebagai lawan dari kebanyakan rasa lainnya, jika batas bawah pada kuantifier0
dapat dihilangkan, misalnya.{,5}
setara dengan.{0,5}
.Adapun subrutin, perbedaan utama antara subrutin PCRE dan subrutin Ruby, adalah bahwa sintaks Ruby adalah satu byte lebih panjang
(?n)
vs\g<n>
, tetapi subrutin Ruby dapat digunakan untuk menangkap, sedangkan PCRE me-reset menangkap setelah subrutin selesai.Terakhir, Ruby memiliki semantik berbeda untuk pengubah yang berhubungan dengan jalur dibandingkan kebanyakan rasa lainnya. Pengubah yang biasa disebut
m
dengan citarasa lain selalu menyala di Ruby. Jadi^
dan$
selalu cocok dengan awal dan akhir garis, tidak hanya awal dan akhir string. Ini dapat menghemat satu byte jika Anda memerlukan perilaku ini, tetapi akan dikenakan biaya tambahan byte jika tidak, karena Anda harus mengganti^
dan$
dengan\A
dan\z
, masing-masing. Selain itu, pengubah yang biasanya disebuts
(yang membuat.
umpan baris cocok) disebutm
di Ruby sebagai gantinya. Ini tidak mempengaruhi jumlah byte, tetapi harus diingat untuk menghindari kebingungan.Python
Python memiliki rasa yang kuat, tapi saya tidak mengetahui adanya fitur yang sangat berguna yang tidak akan Anda temukan di tempat lain.
Namun , ada rasa alternatif yang dimaksudkan untuk menggantikan
re
modul di beberapa titik, dan yang mengandung banyak fitur menarik. Selain menambahkan dukungan untuk rekursi, tampilan panjang variabel dan operator kombinasi kelas karakter, ini juga memiliki fitur unik pencocokan fuzzy . Intinya, Anda dapat menentukan sejumlah kesalahan (penyisipan, penghapusan, pergantian) yang diizinkan, dan mesin juga akan memberi Anda perkiraan kecocokan.Naskah ECMAS
Rasa ECMAScript sangat terbatas, dan karenanya jarang sangat berguna untuk bermain golf. Satu-satunya hal yang terjadi adalah kelas karakter kosong yang dinegasikan
[^]
untuk mencocokkan karakter apa pun serta kelas karakter kosong yang gagal tanpa syarat[]
(sebagai lawan dari yang biasa(?!)
). Sayangnya, rasanya tidak memiliki fitur yang membuat yang terakhir berguna untuk masalah normal.Lua
Lua memiliki citarasa yang cukup unik, yang cukup terbatas (mis. Anda bahkan tidak dapat mengukur kelompok) tetapi memang hadir dengan sejumlah fitur yang berguna dan menarik.
%b
itu mendukung sintaks yang sangat kompak untuk mencocokkan string seimbang. Misalnya%b()
cocok dengan(
dan kemudian semuanya hingga cocok)
(melewatkan dengan benar pasangan yang cocok dalam).(
dan)
dapat berupa dua karakter apa pun di sini.Dorongan
Rasa regex Boost pada dasarnya adalah Perl. Namun, ia memiliki beberapa fitur baru yang bagus untuk penggantian regex, termasuk perubahan kasus dan persyaratan . Yang terakhir ini unik untuk Meningkatkan sejauh yang saya ketahui.
sumber
.?+
setara dengan.*
?Ketahui kelas karakter Anda
Sebagian besar rasa regex memiliki kelas karakter yang telah ditentukan. Misalnya,
\d
cocok dengan angka desimal, yang tiga byte lebih pendek dari[0-9]
. Ya, mereka mungkin sedikit berbeda karena\d
mungkin juga cocok dengan angka Unicode dalam beberapa rasa, tetapi untuk sebagian besar tantangan ini tidak akan membuat perbedaan.Berikut adalah beberapa kelas karakter yang ditemukan di sebagian besar rasa regex:
Selain itu, kami juga memiliki:
yang merupakan versi negasi di atas.
Pastikan untuk memeriksa rasa Anda untuk kelas karakter tambahan apa pun yang mungkin dimilikinya. Sebagai contoh, PCRE memiliki
\R
untuk baris baru dan Lua bahkan memiliki kelas-kelas seperti huruf kecil dan huruf besar.(Terima kasih kepada @HamZa dan @ MartinBüttner karena menunjukkan ini)
sumber
\R
untuk baris baru di PCRE.Jangan repot-repot dengan kelompok yang tidak menangkap (kecuali ...)
Kiat ini berlaku untuk (setidaknya) semua rasa yang diilhami Perl.
Ini mungkin jelas, tetapi (ketika tidak bermain golf) adalah praktik yang baik untuk menggunakan kelompok yang tidak menangkap
(?:...)
jika memungkinkan. Kedua karakter tambahan?:
ini boros ketika bermain golf, jadi gunakan saja grup menangkap, bahkan jika Anda tidak akan mereferensi mereka.Ada satu pengecualian (jarang): jika Anda kebetulan pada grup referensi
10
-ulang setidaknya 3 kali, Anda sebenarnya dapat menyimpan byte dengan mengubah grup sebelumnya menjadi grup yang tidak menangkap, sehingga semua\10
itu menjadi\9
s. (Trik serupa berlaku, jika Anda menggunakan grup11
setidaknya 5 kali dan seterusnya.)sumber
$9
alih-alih$10
atau$11
sekali menghemat satu byte. Mengubah$10
menjadi$9
membutuhkan satu?:
, yaitu dua byte, jadi Anda akan membutuhkan tiga$10
untuk menyimpan sesuatu. Mengubah$11
menjadi$9
membutuhkan dua?:
s yang merupakan empat byte, jadi Anda akan membutuhkan lima$11
s untuk menyimpan sesuatu (atau lima$10
dan$11
digabungkan).Rekursi untuk penggunaan kembali pola
Sejumlah rekursi rasa mendukung ( setahu saya , Perl, PCRE dan Ruby). Bahkan ketika Anda tidak mencoba untuk memecahkan masalah rekursif, fitur ini dapat menyimpan banyak byte dalam pola yang lebih rumit. Tidak perlu melakukan panggilan ke grup lain (bernama atau bernomor) di dalam grup itu sendiri. Jika Anda memiliki pola tertentu yang muncul beberapa kali di regex Anda, cukup kelompokkan dan lihat di luar grup itu. Ini tidak berbeda dari panggilan subrutin dalam bahasa pemrograman normal. Jadi, bukannya
di Perl / PCRE yang dapat Anda lakukan:
atau di Ruby:
asalkan itu adalah grup pertama (tentu saja, Anda dapat menggunakan nomor apa pun dalam panggilan rekursif).
Perhatikan bahwa ini tidak sama dengan backreference (
\1
). Referensi ulang cocok dengan string yang sama persis dengan kelompok yang cocok terakhir kali. Panggilan subrutin ini benar-benar mengevaluasi pola lagi. Sebagai contoh untuksomeComplexPatternHere
mengambil kelas karakter yang panjang:Ini akan cocok dengan sesuatu seperti
Perhatikan bahwa Anda tidak dapat menggunakan referensi-ulang di sini sambil mempertahankan perilaku. Referensi balik akan gagal pada string di atas, karena
B
dan0
dan!
tidak sama. Namun, dengan panggilan subrutin, polanya sebenarnya dievaluasi kembali. Pola di atas sama denganMenangkap panggilan subrutin
Satu catatan hati-hati untuk Perl dan PCRE: jika grup
1
dalam contoh di atas berisi grup lebih lanjut, maka panggilan subrutin tidak akan mengingat hasil tangkapan mereka. Pertimbangkan contoh ini:Ini tidak akan cocok
karena setelah panggilan subrutin kembali, penangkapan baru grup
2
akan dibuang. Alih-alih, pola ini akan cocok dengan string ini:Ini berbeda dari Ruby, di mana panggilan subrutin memang mempertahankan tangkapan mereka, sehingga regex Ruby yang setara
(\w(\d):)\2 \g<1>\2 \g<1>\2
akan cocok dengan yang pertama dari contoh di atas.sumber
\1
untuk Javascript. Dan PHP juga (kurasa).(..)\1
akan cocokabab
tetapi gagalabba
padahal(..)(?1)
akan cocok dengan yang terakhir. Ini sebenarnya adalah panggilan subrutin dalam arti bahwa ekspresi diterapkan lagi, alih-alih secara harfiah cocok dengan yang cocok terakhir kali.(?=a.b.c)(.[0_B!$]){3}d
Menyebabkan pertandingan gagal
Saat menggunakan regex untuk memecahkan masalah komputasi atau mencocokkan bahasa yang sangat tidak biasa, kadang-kadang perlu untuk membuat cabang dari pola gagal terlepas di mana pun Anda berada di string. Pendekatan naif adalah dengan menggunakan lookahead negatif yang kosong:
Isi (pola kosong) selalu cocok, sehingga tampilan negatif selalu gagal. Tetapi lebih sering daripada tidak, ada opsi yang lebih sederhana: cukup gunakan karakter yang Anda tahu tidak akan pernah muncul di input. Misalnya, jika Anda tahu input Anda akan selalu hanya terdiri dari digit, Anda bisa menggunakan saja
atau karakter non-digit, non-meta lainnya yang menyebabkan kegagalan.
Bahkan jika input Anda berpotensi mengandung substring apa pun, ada cara yang lebih pendek daripada
(?!)
. Rasa apa pun yang memungkinkan jangkar muncul dalam suatu pola yang bertentangan dengan akhir, dapat menggunakan salah satu dari solusi 2 karakter berikut:Namun perlu dicatat bahwa beberapa rasa akan memperlakukan
^
dan$
sebagai karakter literal di posisi ini, karena mereka jelas tidak masuk akal sebagai jangkar.Dalam rasa ECMAScript ada juga solusi 2 karakter yang agak elegan
Ini adalah kelas karakter kosong, yang mencoba memastikan bahwa karakter berikutnya adalah salah satu dari yang ada di kelas - tetapi tidak ada karakter di kelas, jadi ini selalu gagal. Perhatikan bahwa ini tidak akan berhasil dalam citarasa lain, karena kelas karakter biasanya tidak dapat kosong.
sumber
Optimalkan Anda ATAU
Setiap kali Anda memiliki 3 atau lebih alternatif di RegEx Anda:
Periksa untuk melihat apakah ada awal yang umum:
Dan mungkin bahkan akhir yang umum?
Catatan: 3 hanyalah awal dan akan menjelaskan panjang yang sama, 4+ akan membuat perbedaan
Tetapi bagaimana jika tidak semuanya memiliki awalan yang sama? (spasi hanya ditambahkan untuk kejelasan)
Kelompokkan mereka, selama aturan 3+ masuk akal:
Atau bahkan menggeneralisasi jika entropi memuaskan pengguna kami:
^ dalam hal ini kami yakin kami tidak mendapatkan
clue
ataucrown
slack
Ryan
Ini "menurut beberapa tes" juga meningkatkan kinerja, karena menyediakan jangkar untuk memulai.
sumber
aqua|aquamarine
→aqua(|marine)
atauaqua(marine)?
.Yang ini cukup sederhana, tetapi layak disebutkan:
Jika Anda mendapati diri Anda mengulang kelas karakter,
[a-zA-Z]
Anda mungkin bisa menggunakan[a-z]
dan menambahkani
( case- i nsensitive modifier) ke regex Anda.Misalnya, di Ruby, dua regex berikut ini setara:
/[a-zA-Z]+\d{3}[a-zA-Z]+/
/[a-z]+\d{3}[a-z]/i
- 7 byte lebih pendekDalam hal ini, pengubah lainnya dapat mempersingkat panjang total Anda juga. Alih-alih melakukan ini:
/(.|\n)/
yang sesuai dengan karakter APAPUN (karena dot tidak sesuai newline), menggunakan s perapian di tungku-line modifier
s
, yang membuat baris baru dot pertandingan././s
- 3 byte lebih pendekDi Ruby, ada satu ton Kelas Karakter bawaan untuk regex. Lihat halaman ini dan cari "Karakter Properties".
Contoh yang bagus adalah "Simbol Mata Uang". Menurut Wikipedia ada satu ton simbol mata uang yang mungkin, dan untuk menempatkannya dalam kelas karakter akan sangat mahal (
[$฿¢₡Ð₫€.....
]) sedangkan Anda bisa mencocokkannya dengan 6 byte:\p{Sc}
sumber
s
pengubah tidak didukung. :( Tapi di sana Anda dapat menggunakan/[^]/
trik milik JavaScript .(.|\n)
bahkan tidak bekerja dalam beberapa rasa, karena.
sering juga tidak cocok dengan jenis pemisah garis lainnya. Namun, cara biasa untuk melakukan ini (tanpas
) adalah[\s\S]
byte yang sama dengan(.|\n)
.Pengurai bahasa yang sederhana
Anda bisa membuat parser yang sangat sederhana dengan seperti RE
\d+|\w+|".*?"|\n|\S
. Token yang harus Anda cocokkan dipisahkan dengan karakter RE 'atau'.Setiap kali mesin RE mencoba untuk mencocokkan pada posisi saat ini dalam teks, itu akan mencoba pola pertama, kemudian yang kedua, dll. Jika gagal (pada karakter spasi di sini misalnya), itu bergerak dan mencoba pertandingan lagi . Ketertiban itu penting. Jika kami menempatkan
\S
istilah sebelum\d+
istilah, maka\S
akan cocok terlebih dahulu pada karakter non-spasi yang akan merusak pengurai kami.Itu
".*?"
String matcher menggunakan pengubah non-serakah sehingga kita hanya mencocokkan satu string pada suatu waktu. Jika RE Anda tidak memiliki fungsi non-serakah, Anda dapat menggunakan"[^"]*"
yang setara.Contoh Python:
Contoh Python Golf:
Anda dapat menyesuaikan pola dan urutannya untuk bahasa yang Anda harus cocok. Teknik ini berfungsi baik untuk ekspresi JSON, HTML dasar, dan numerik. Ini telah berhasil digunakan berkali-kali dengan Python 2, tetapi harus cukup umum untuk bekerja di lingkungan lain.
sumber
\K
bukannya tampilan positif di belakangPCRE dan Perl mendukung urutan pelarian
\K
, yang mengatur ulang awal pertandingan. Ituab\Kcd
akan membutuhkan string input Anda berisiabcd
tetapi kecocokan yang dilaporkan hanya akancd
.Jika Anda menggunakan tampilan positif di belakang pada awal pola Anda (yang mungkin merupakan tempat yang paling mungkin), maka dalam kebanyakan kasus, Anda dapat menggunakan
\K
sebagai gantinya dan menyimpan 3 byte:Ini setara untuk sebagian besar tujuan, tetapi tidak sepenuhnya. Perbedaan membawa keuntungan dan kerugian:
(?<=ab*)
. Tetapi dengan\K
Anda dapat menempatkan segala macam pola di depannya! Begituab*\K
berhasil. Ini sebenarnya membuat teknik ini jauh lebih kuat dalam kasus-kasus di mana itu berlaku.\K
bagian regex sedang ditelusuri kembali seperti yang lainnya.Kekurangan: Seperti yang mungkin Anda ketahui, beberapa korek api pada regex tidak bisa tumpang tindih. Seringkali, lookaround digunakan untuk mengatasi keterbatasan ini sebagian, karena lookahead dapat memvalidasi bagian dari string yang sudah dikonsumsi oleh pertandingan sebelumnya. Jadi, jika Anda ingin mencocokkan semua karakter yang mengikuti
ab
Anda mungkin menggunakan(?<=ab).
. Diberikan inputini akan cocok dengan yang kedua
a
dan yangc
. Ini tidak dapat direproduksi dengan\K
. Jika Anda menggunakanab\K.
, Anda hanya akan mendapatkan pertandingan pertama, karena sekarangab
tidak ada dalam pencarian.sumber
\K
urutan lolos dalam pernyataan positif, awal pertandingan yang dilaporkan dapat lebih besar dari akhir pertandingan.ababc
, tidak ada cara untuk mencocokkan keduaa
danc
dengan\K
. Anda hanya akan mendapatkan satu pertandingan.\G
.
dari pertandingan terakhir sebenarnya adalaha
.Mencocokkan karakter apa pun
Rasa ECMAScript kurang memiliki
s
pengubah yang.
cocok dengan karakter apa pun (termasuk baris baru). Ini berarti tidak ada solusi satu karakter untuk mencocokkan karakter yang sepenuhnya arbitrer. Solusi standar dalam rasa lain (ketika seseorang tidak ingin menggunakans
karena suatu alasan) adalah[\s\S]
. Namun, ECMAScript adalah satu-satunya rasa (untuk pengetahuan saya) yang mendukung kelas karakter kosong, dan karenanya memiliki alternatif yang jauh lebih pendek:[^]
. Ini adalah kelas karakter kosong yang dinegasikan - yaitu, cocok dengan karakter apa pun.Bahkan untuk citarasa lain, kita dapat belajar dari teknik ini: jika kita tidak ingin menggunakan
s
(misalnya karena kita masih perlu makna biasa.
di tempat lain), masih bisa ada cara yang lebih pendek untuk mencocokkan kedua baris baru dan karakter yang dapat dicetak, asalkan ada beberapa karakter yang kita tahu tidak muncul di input. Katakanlah, kami sedang memproses angka yang dibatasi oleh baris baru. Kemudian kita dapat mencocokkan karakter apa pun dengan[^!]
, karena kita tahu itu!
tidak akan pernah menjadi bagian dari string. Ini menghemat dua byte di atas naif[\s\S]
atau[\d\n]
.sumber
\N
berarti persis apa yang.
berarti di luar/s
mode, kecuali itu tidak terpengaruh oleh mode.Gunakan grup atom dan quantifiers posesif
Saya menemukan kelompok atom (
(?>...)
) dan bilangan posesif (?+
,*+
,++
,{m,n}+
) kadang-kadang sangat berguna untuk golf. Ini cocok dengan string dan tidak memungkinkan untuk mengulangi kembali nanti. Jadi itu hanya akan cocok dengan string pertama yang cocok yang ditemukan oleh mesin regex.Misalnya: Untuk mencocokkan string dengan angka ganjil
a
di awal, yang tidak diikuti oleh lebih banyaka
, Anda dapat menggunakan:Ini memungkinkan Anda untuk menggunakan hal-hal seperti
.*
bebas, dan jika ada kecocokan yang jelas, tidak akan ada kemungkinan lain yang cocok dengan terlalu banyak atau terlalu sedikit karakter, yang dapat merusak pola Anda.Di .NET regex (yang tidak memiliki quantifiers posesif), Anda dapat menggunakan ini untuk melompati grup 1 kelipatan terbesar dari 3 (dengan maksimum 30) kali (tidak bermain golf dengan sangat baik):
sumber
Lupakan grup yang ditangkap setelah subekspresi (PCRE)
Untuk regex ini:
Jika Anda ingin menghapus \ 2 setelah grup 1, Anda dapat menggunakan rekursi:
Ini akan cocok
aa
dengan yang sebelumnya tidak. Terkadang Anda juga bisa menggunakan??
atau bahkan?
menggantikannya{0}
.Ini mungkin berguna jika Anda sering menggunakan rekursi, dan beberapa referensi balik atau kelompok bersyarat muncul di tempat yang berbeda di regex Anda.
Juga perhatikan bahwa kelompok atom diasumsikan untuk rekursi dalam PCRE. Jadi ini tidak akan cocok dengan satu huruf
a
:Saya belum mencobanya dalam rasa lain.
Untuk lookaheads, Anda juga dapat menggunakan negatif ganda untuk tujuan ini:
sumber
Ekspresi opsional
Terkadang berguna untuk mengingatnya
adalah sebagian besar sama dengan
Namun ada perbedaan kecil: dalam kasus pertama, grup tersebut menangkap
abc
atau tidak menangkap sama sekali. Kasus terakhir akan membuat referensi balik gagal tanpa syarat. Dalam ekspresi kedua, grup akan menangkapabc
atau string kosong, di mana case terakhir akan membuat pertandingan referensi-ulang tanpa syarat. Untuk meniru perilaku yang terakhir dengan?
Anda harus mengelilingi segala sesuatu di grup lain yang akan menelan biaya dua byte:Versi yang digunakan
|
juga berguna ketika Anda ingin membungkus ekspresi dalam beberapa bentuk grup lain dan tidak peduli tentang penangkapan:Akhirnya, trik ini juga dapat diterapkan pada ungreedy di
?
mana ia menyimpan satu byte bahkan dalam bentuk mentahnya (dan akibatnya 3 byte bila dikombinasikan dengan bentuk grup lain):sumber
Beberapa lookaheads yang selalu cocok (.NET)
Jika Anda memiliki 3 atau lebih konstruksi lookahead yang selalu cocok (untuk menangkap subekspresi), atau ada penjumlahan pada lookahead diikuti oleh sesuatu yang lain, jadi mereka harus berada dalam kelompok yang tidak perlu ditangkap:
Ini lebih pendek:
di mana
a
seharusnya tidak menjadi nama grup yang ditangkap. Anda tidak dapat menggunakan|
untuk maksud hal biasa dib
danc
tanpa menambahkan sepasang tanda kurung.Sayangnya, menyeimbangkan kelompok-kelompok di kondisional tampak buggy, membuatnya tidak berguna dalam banyak kasus.
sumber