Dapatkah Anda membuat bagian dari regex case-insensitive?

100

Saya telah melihat banyak contoh dalam membuat ekspresi reguler peka huruf besar kecil. Yang saya ingin tahu adalah memiliki sebagian dari ekspresi peka huruf besar kecil.

Misalnya, saya memiliki string seperti ini:

fooFOOfOoFoOBARBARbarbarbAr

Bagaimana jika saya ingin mencocokkan semua kemunculan "foo" apa pun hurufnya, tetapi saya hanya ingin mencocokkan "BAR" huruf besar?

Solusi ideal adalah sesuatu yang bekerja di seluruh rasa regex tetapi saya tertarik untuk mendengarkan bahasa khusus juga (Terima kasih Espo )

Edit

Tautan yang disediakan Espo sangat membantu. Ada contoh bagus di sana tentang mengaktifkan dan menonaktifkan pengubah dalam ekspresi.

Untuk contoh buatan saya, saya dapat melakukan sesuatu seperti ini:

(?i)foo*(?-i)|BAR

yang membuat pencocokan tidak peka huruf besar / kecil hanya untuk bagian foo dari pertandingan.

Itu tampaknya berfungsi di sebagian besar implementasi regex kecuali Javascript, Python, dan beberapa lainnya (seperti yang disebutkan Espo).

Yang besar yang saya ingin tahu tentang (Perl, PHP, .NET) semua mendukung perubahan mode inline.

Mark Biek
sumber
Pertanyaan ini telah ditambahkan ke FAQ Ekspresi Reguler Stack Overflow , di bawah "Pengubah".
aliteralmind

Jawaban:

88

Perl memungkinkan Anda membuat bagian dari ekspresi reguler Anda tidak peka huruf besar kecil dengan menggunakan pengubah pola (? I :).

Ragam regex modern memungkinkan Anda menerapkan pengubah hanya ke sebagian dari ekspresi reguler. Jika Anda memasukkan pengubah (? Ism) di tengah regex, pengubah hanya berlaku untuk bagian dari regex di sebelah kanan pengubah. Anda dapat mematikan mode dengan mendahului mereka dengan tanda minus. Semua mode setelah tanda minus akan dimatikan. Misalnya (? I-sm) mengaktifkan case insensitivity, dan mematikan mode single-line dan multi-line.

Tidak semua rasa regex mendukung ini. JavaScript dan Python menerapkan semua pengubah mode ke seluruh ekspresi reguler. Mereka tidak mendukung sintaks (? -Ismx), karena mematikan opsi tidak ada gunanya ketika pengubah mode diterapkan ke seluruh ekspresi reguler. Semua opsi dinonaktifkan secara default.

Anda dapat dengan cepat menguji bagaimana ragam regex yang Anda gunakan pengubah mode pegangan. Regex (? I) te (? - i) st harus cocok dengan test dan TEst, tetapi tidak teST atau TEST.

Sumber

Espo
sumber
6

Bahasa apa yang Anda gunakan? Cara standar untuk melakukan ini adalah seperti / ([Ff] [Oo] {2} | BAR) / dengan sensitivitas huruf aktif, tetapi di Java, misalnya, ada pengubah sensitivitas huruf (? I) yang membuat semua karakter di sebelah kanannya case insensitive dan (? -i) yang memaksa sensitivitas. Contoh pengubah regex Java itu dapat ditemukan di sini .

akdom
sumber
+1 Mengapa repot-repot membuatnya tidak peka huruf besar / kecil ketika Anda dapat mencocokkan kedua
kasing
11
@NonaUrbiz: Karena ekspresi (?i)foobarlebih mudah dibaca daripada[Ff][Oo]{2}[Bb][Aa][Rr]
Thanatos
1
Dan karena dapat tumbuh dengan cara yang jauh lebih berbulu dan kompleks.
Potong
6

Sayangnya sintaks untuk pencocokan tidak peka huruf besar / kecil tidak umum. Dalam .NET Anda dapat menggunakan bendera RegexOptions.IgnoreCase atau ? I pengubah

aku
sumber
4

Anda bisa menggunakan

(?:F|f)(?:O|o)(?:O|o)

?: Di dalam tanda kurung di .Net berarti non-capturing, dan hanya digunakan untuk mengelompokkan istilah | (atau) pernyataan.

Kibbee
sumber
26
Bukankah "[fF] [oO] [oO]" adalah alternatif yang lebih baik? Untuk contoh yang ada, Anda bahkan bisa melangkah sejauh "[fF] [oO] \ {2}" ;-)
Tomalak
4

Memang benar seseorang dapat mengandalkan pengubah sebaris seperti yang dijelaskan di Mengaktifkan dan Menonaktifkan Mode Hanya untuk Sebagian Ekspresi Reguler :

Regex (?i)te(?-i)stharus cocok dengan test dan TEst, tetapi tidak teSTatau TEST.

Namun, sedikit lebih banyak fitur yang didukung adalah (?i:...)grup pengubah sebaris (lihat Rentang Pengubah ). Sintaksnya adalah (?i:, lalu pola yang ingin Anda buat tidak peka-kasus, dan kemudian a ).

(?i:foo)|BAR

Kebalikan : Jika pola dikompilasi dengan kasus pilihan sensitif dan Anda perlu untuk membuat bagian dari kasus regex sensitif, Anda menambahkan -setelah ?: (?-i:...).

Contoh penggunaan dalam berbagai bahasa (membungkus korek api dengan tanda kurung siku):

  • - preg_replace("~(?i:foo)|BAR~", '<$0>', "fooFOOfOoFoOBARBARbarbarbAr")( demo )
  • - re.sub(r'(?i:foo)|BAR', r'<\g<0>>', 'fooFOOfOoFoOBARBARbarbarbAr')( demo ) (catatan Python remendukung grup pengubah sebaris sejak Python 3.6)
  • / / - Regex.Replace("fooFOOfOoFoOBARBARbarbarbAr", "(?i:foo)|BAR", "<$&>")( demo )
  • - "fooFOOfOoFoOBARBARbarbarbAr".replaceAll("(?i:foo)|BAR", "<$0>")( demo )
  • - $s =~ s/(?i:foo)|BAR/<$&>/g( demo )
  • - "fooFOOfOoFoOBARBARbarbarbAr".gsub(/(?i:foo)|BAR/, '<\0>')( demo )
  • - gsub("((?i:foo)|BAR)", "<\\1>", "fooFOOfOoFoOBARBARbarbarbAr", perl=TRUE)( demo )
  • - "fooFOOfOoFoOBARBARbarbarbAr".replacingOccurrences(of: "(?i:foo)|BAR", with: "<$0>", options: [.regularExpression])
  • - (menggunakan RE2) - regexp.MustCompile(`(?i:foo)|BAR`).ReplaceAllString( "fooFOOfOoFoOBARBARbarbarbAr", `<${0}>`)( demo )

Tidak didukung di , , , std::regex, , .

Wiktor Stribiżew
sumber