Ekspresi reguler terpendek

59

Misi Anda adalah menulis ekspresi reguler terpendek yang tidak ada string yang cocok, termasuk string kosong.

Kiriman harus memiliki formulir ini ("notasi literal"):

/pattern/optional-flags

Kemenangan regexp terpendek. Ukuran regexp dihitung dalam karakter. (termasuk garis miring dan bendera)

Tolong jelaskan cara kerja regexp Anda (jika tidak sepele)

Terima kasih, dan bersenang-senanglah!

xem
sumber
Ini menginspirasi pertanyaan dari saya. Saya akan menunggu beberapa hari. Tidak ingin 2 pertanyaan regex aktif pada saat yang sama
Cruncher
13
"Valid" sesuai dengan implementasi yang mana? Saya baru saja menemukan yang lucu yang Perl baik-baik saja (dan itu valid menurut satu-satunya tata bahasa RE yang bisa saya temukan , tetapi modul grep dan Python menolak)
Josh Caswell
1
Ya, dialek regex apa? Ada banyak yang berbeda.
hippietrail
1
Tetapi bagaimana dengan nama-nama Presiden? xkcd.com/1313
Carl Witthoft
@CarlWitthoft Anda harus menjadi program untuk berpartisipasi dalam kontes itu: codegolf.stackexchange.com/q/17718/2180
boothby

Jawaban:

53

6 karakter

Mengikuti jawaban primo dan Peter Taylor, dan sebuah petunjuk dari man perlre:

/(?!)/

Regex yang kompatibel dengan perl ini cocok dengan string kosong yang tidak diikuti oleh string kosong lainnya.

Nate Eldredge
sumber
+1 - Ini mungkin jawaban terpendek yang secara portable (bersamaan dengan /x\by/, tetapi jika saya benar-benar harus menggunakan regex seperti ini - untuk alasan apa pun - maka jawaban ini juga yang paling jelas)
Martin Ender
@ m.buettner: Terima kasih. primo /(*FAIL)/mungkin lebih jelas. (Dan benar-benar man perlrememberikannya dengan menyebutkan bahwa milik saya benar-benar meluas ke internalnya.)
Nate Eldredge
/(*FAIL)/meskipun tidak portabel. Dan bahkan di Perl, saya pikir itu fitur yang lebih jelas daripada tampilan negatif.
Martin Ender
3
Anda mendapatkan lookaround di hampir semua rasa populer (terinspirasi-Perl) hari ini, sedangkan saya belum pernah melihat kata kerja kontrol ini di mana pun kecuali di Perl.
Martin Ender
1
Bahkan, dokumentasi Perl (dan -Mre=debug) mengatakan bahwa (?!)ini dioptimalkan (*FAIL)oleh Perl regex optimizer ( OPFAILmenurut -Mre=debug). Juga, saya tidak berpikir saya melihat di (*FAIL)luar Perl 5 (dan Perl 6, di mana namanya <!>).
Konrad Borowski
39

8 karakter

/(?=a)b/

Kami memerlukan string berisi karakter yang keduanya adan b, yang jelas tidak mungkin.

Peter Taylor
sumber
19
/(?!x)x/terlihat lebih mustahil ;-)
Howard
@PeterTaylor dimana?
o0 '.
@ Lohoris, di mana apa?
Peter Taylor
@ PeterTaylor di mana dia meletakkan aturan-aturan aneh yang Anda bicarakan, saya tidak bisa menemukannya.
o0 '.
7
teman-teman, maaf untuk penghitungan yang saya pilih, saya pikir akan lebih mudah untuk memasukkan garis miring karena bendera opsional yang bisa datang setelah mereka.
xem
31

5 karakter

Tidak seperti semua orang yang menyalahgunakan $dan ^... ini benar-benar berfungsi di Perl:

/V\A/

\A cocok dengan awal string.

stan
sumber
Ini bekerja dengan baik ^.
Tomas
28

8 karakter

/\w\b\w/

Batas kata ( \b) dikelilingi oleh karakter 'kata' ( \w- salah satu [_a-zA-Z0-9]). Ini tidak cocok karena salah satu karakter sebelum atau mengikuti batas kata harus bukan karakter 'kata'.

Ngomong-ngomong: ini mirip dengan ekspresi yang tak tertandingi

/\W\b\W/

di mana \Wberarti karakter non-'kata'.

Sven Hohenstein
sumber
Ini adalah 8 karakter sesuai dengan aturan kompetisi, karena garis miring pembungkus /dihitung. Lihat entri OP, misalnya . Itu entri yang bagus!
Josh Caswell
Mungkin juga pemenang (atau terikat dengan entri Peter Taylor ), mengingat masalah yang tergantung pada implementasi dengan beberapa entri yang lebih pendek!
Josh Caswell
Sangat elegan! Saya pikir pasti ada sesuatu seperti ini!
Tomas
22

4 karakter

/$a/

mencari "a" setelah akhir string.

atau

/a^/

mencari sebelum string.

xem
sumber
20
Mengapa memposting pertanyaan jika Anda tahu bahwa ada solusi dua-char?
Peter Taylor
3
@ Howard: Itu cocok dengan string kosong: jsfiddle.net/RjLxJ
ProgramFOX
10
Mengapa saya selalu menemukan masalah ini setelah solusi yang tidak ada
duanya
43
-1: Menempatkan ^dan $dalam posisi "ilegal" hanya menyebabkan mereka diperlakukan sebagai karakter biasa. Contoh pertama Anda sesuai dengan literal $adalam seddan mungkin program lain.
Ben Jackson
2
@ Ben Jackson, itu tidak benar untuk POSIX EREs. Coba echo 'a^b' | grep 'a^b'vs echo 'a^b' | grep -E 'a^b'.. Lihatlah 9.4.9 ERE Expression Anchoring
laindir
21

5 karakter

/$.^/

/$^/ akan cocok dengan string kosong, sedangkan yang membutuhkan karakter di antara tidak akan.

Brian Glaz
sumber
6
Sayangnya ini cocok "$a^"(atau apa pun di tempat 'a') di Perl ( dan mungkin sed ). Tapi tetap saja bagus!
Josh Caswell
@ JoshCaswell: Saya kira perl mungkin menafsirkan $.sebagai variabel nomor baris saat ini. Yang mungkin kosong, dalam hal ini akan menjadi /^/.
MvG
Karakter 'antara' berarti string satu karakter.
jwg
3
@ jwg perhatikan yang tertukar ^dan$
mniip
Saya mencoba pola '$^'dengan grep, tetapi sayangnya itu cocok dengan string '$^'. Grep smartass.
joeytwiddle
19

9 karakter

Saya tidak yakin tetapi /[^\S\s]/harus tidak cocok karena itu berarti bukan karakter apa pun, tetapi setidaknya salah satunya.

pengguna14325
sumber
Anda tidak membutuhkannya +.
Peter Taylor
10
/ [^ \ S \ s] / = 9 karakter
xem
19

6 karakter

Saya pikir regex yang saya buat ini akan berfungsi:

/\b\B/

Ini cocok dengan batas kata ( \b) yang bukan batas kata ( \B). Yang mana mustahil - apakah saya benar-benar harus menjelaskan ini kepada Anda?

The Guy with The Hat
sumber
bukankah ini mencari batas kata diikuti oleh batas bukan kata?
grexter89
1
@ grexter89 Ya, tetapi mereka tidak dapat memiliki karakter di antaranya. yaitu Batas dan non-batas harus menempati ruang yang sama.
The Guy with The Hat
2
Saya suka yang ini. Tangkapan yang bagus.
Primo
18

4 karakter

(Khusus ECMAScript)

/[]/

Dalam rasa lain ini bukan kelas karakter yang valid ( ]akan dianggap sebagai karakter di kelas, jadi ekspresi tidak valid, karena kelas tidak pernah ditutup), tetapi standar ECMAScript menerima kelas karakter kosong. Karena ini adalah kelas, ia harus cocok dengan satu karakter (jadi string kosong tidak cocok), tetapi karena tidak satu karakter dimasukkan, tidak ada karakter aktual yang akan cocok.

Martin Ender
sumber
Bukankah ini cocok dengan string kosong meskipun Anda mengatakan itu harus cocok dengan karakter? Atau apakah Anda pikir ini adalah ilegal: /[]{0}/. (Mz. Meskipun jawaban saya sebagian mirip dengan jawaban Anda, saya benar-benar membaca jawaban Anda setelah menulis milik saya.)
nl-x
@ nl-x paste ke konsol browser Anda: /[]/.test(""). mengembalikan salah. kelas karakter tidak pernah dapat mencocokkan string kosong, bahkan jika itu tidak mengandung karakter (saya membayangkan mereka diimplementasikan seperti "JIKA karakter berikutnya dalam string adalah salah satu yang terdaftar, cocok; ELSE gagal"). /[]{0}/legal (dalam ECMAScript) dan tidak cocok dengan string kosong ... namun, saya tidak yakin bagaimana itu relevan dengan jawaban saya.
Martin Ender
Gagal di Ruby 2.0
Nakilon
@Nakilon tentu saja. Ruby tidak menerapkan bumbu ECMAScript.
Martin Ender
15

6 karakter

/b++b/

Possessive quantifier mencari sebanyak mungkin b, lalu 1 lagi. 6 karakter tetapi poin untuk simetri?

VBCPP
sumber
Hah ... Saya baru belajar fitur baru. Tampaknya, keterampilan regex saya sudah ketinggalan zaman. Terima kasih, dan +1.
Ilmari Karonen
8

6 karakter

/(\1)/

Bukan pemenang, tapi saya pikir itu menyenangkan. grep dan Python sama-sama muntah dalam hal ini, tetapi Perl tampaknya tidak keberatan.

Tampaknya sangat tergantung pada implementasi (yang tidak mengejutkan, mengingat keanehannya). Bob melaporkan di bawah bahwa itu cocok dengan apa pun di mesin regex JavaScript.

Josh Caswell
sumber
Mesin regex .NET tampaknya menerimanya.
Bob
Dan selalu cocok (string kosong) tidak peduli apa pun masukan pada JS
Bob
8

Mungkin sedikit curang, tapi ...

\0

... tidak ada bandingannya dalam POSIX regex di hampir semua, jika tidak semua, implementasi. RE DASAR dan RE yang DIPERPANJANG, bahkan.

Dan POSIX RE tidak perlu garis miring dan bendera yang dimiliki PCRE.

mirabilos
sumber
+1 Bagus !! Sayangnya, sol 0tidak bekerja di PERL. "0"=~0itu benar ...
Tomas
-satunya \0ITYM? Ya, sebagian besar implementasi perlre (1) dan PCRE tidak menggunakan string C tetapi buffer ukuran-terikat, di mana trik ini tidak akan berfungsi, tetapi sebagian besar implementasi POSIX RE bekerja pada string C.
mirabilos
5

5 karakter

/^.^/

Cocokkan string yang dimulai dengan karakter tunggal apa pun sebelum string dimulai.

P̲̳x͓L̳
sumber
6
Juga cocok dengan tali".^"
stan
@ boothby: dalam bahasa apa sajakah yang cocok? dalam Python tidak. re.findall(r'^.^', '.^', re.DEBUG)
P̲̳x͓L̳
8
+1 untuk menggunakan operator manga (lihat stackoverflow.com/questions/3618340/... )
prototipe
@Boothby ^dan .bukan metacharacters yang literal, yang perlu untuk melarikan diri
P̲̳x͓L̳
1
Itu rusak di Perl. Pertanyaan ini benar-benar harus menetapkan beberapa aturan dasar tentang bahasa.
stan
5

4 char:

/.^/

Bekerja dengan GNU grep 2.5.1 dan egrep.

RSFalcon7
sumber
/.^/= 4 karakter.
Alexey Popkov
Mengapa Anda membutuhkannya //? itu tidak diperlukan di mana-mana ;-)
RSFalcon7
Garis miring pembungkus /dihitung, lihat pertanyaan asli ("termasuk garis miring dan bendera") dan entri OP .
Alexey Popkov
Baik! Saya rindu membaca :(
RSFalcon7
Tidak, untuk alasan yang sama dengan yang di bawah ini: Sebenarnya, "^" hanya khusus jika di awal pola. "^" Apa pun setelah hal lain tidak perlu diloloskan, jadi jawaban ini salah.
mirabilos
4

Perl 6 (5 karakter)

/<!>/

Penyalahgunaan aturan sorta (karena reg 6 Perl berbeda, dan tidak kompatibel dengan regard stardard menurut desain), tapi saya tidak peduli. <!>aturan menginformasikan Perl 6 bahwa regex tidak cocok.

Konrad Borowski
sumber
4

6 byte

/(*F)/

Singkatan untuk (*FAIL), didukung oleh mesin regex perl-compatable. Terima kasih kepada @HamZa karena menunjukkan ini.

9 byte

/(*FAIL)/

Harus bekerja dengan mesin regex yang mendukung kata kerja sama sekali. Saya tidak yakin ini benar-benar perlu golf lebih jauh.

primo
sumber
1
Bagaimana cara kerjanya?
stan
@boothby (*FAIL)adalah kata kerja yang selalu gagal.
Primo
@rimo, Anda mungkin hanya menggunakan /(*F)/:)
HamZa
4

4 karakter

/$./

Membutuhkan karakter apa pun setelah string berakhir

c0de Freak
sumber
Mirip dengan dua lainnya, $hanya khusus di akhir pola.
mirabilos
3

4 karakter dengan garis miring 2 tanpa

Di mesin regex bahasa TXR, kelas karakter kosong []tidak cocok dengan karakter, dan karenanya tidak ada string. Ini berlaku seperti ini karena kelas karakter memerlukan kecocokan karakter, dan ketika kosong itu menentukan bahwa tidak ada karakter yang bisa memuaskannya.

Cara lain adalah dengan membalikkan "himpunan semua string termasuk kosong" regex /.*/menggunakan operator komplemen: /~.*/. Komplemen set itu tidak mengandung string sama sekali, sehingga tidak dapat menandingi apa pun.

Ini semua didokumentasikan di halaman manual:

   nomatch
          The  nomatch  regular  expression  represents  the empty set: it
          matches no strings at all, not even the empty string.  There  is
          no  dedicated  syntax  to  directly express nomatch in the regex
          language.  However, the empty character class []  is  equivalent
          to nomatch, and may be considered to be a notation for it. Other
          representations of nomatch are possible: for instance, the regex
          ~.* which is the complement of the regex that denotes the set of
          all possible strings, and thus denotes the empty set. A  nomatch
          has  uses;  for instance, it can be used to temporarily "comment
          out" regular expressions. The regex ([]abc|xyz) is equivalent to
          (xyz), since the []abc branch cannot match anything. Using [] to
          "block" a subexpression allows you to leave it  in  place,  then
          enable it later by removing the "block".

Garis miring bukan bagian dari sintaks regex per se; mereka hanya tanda baca yang membatasi regex dalam notasi S-ekspresi. Saksi:

# match line of input with x variable, and then parse that as a regex
#
$ txr -c '@x
@(do (print (regex-parse x)) (put-char #\newline))' -
ab.*c                               <- input from tty: no slashes.
(compound #\a #\b (0+ wild) #\c)    <- output: AST of regex
Kaz
sumber
terima kasih atas jawaban Anda dan maaf lagi untuk penghitungan tebasan. Saya pikir akan lebih mudah untuk memasukkan mereka jika orang menggunakan bendera.
xem
1

6 karakter

(atau 4, tergantung pada bagaimana Anda melihatnya)

/{,0}/
Tercy
sumber
Gagal di Ruby 2.0
Nakilon
Di mana implementasi regex tidak memberikan kesalahan?
Peter Taylor
Saya hanya mengujinya menggunakan preg_match PHP.
Tercy
1

Ini adalah regex 5 char.

/[]+/

Ini cocok dengan grup kosong 1 kali atau lebih.

SUNTING:

Menghapus jawaban saya untuk rasa lain:

/.{-1}/

Apa pun yang bukan angka di dalam {} akan cocok dengan teks.

Yang ini akan cocok dengan ". {- 1}"

Ismael Miguel
sumber
Perhatikan bahwa ini hanya berfungsi dalam aroma ECMAScript. Di sebagian besar (semua?) Yang lain itu bukan ekspresi yang valid.
Martin Ender
Bukankah itu tidak benar?
Wasi
@Wasi tidak dalam rasa yang sesuai dengan ECMAScript
Martin Ender
0

5 karakter

Semoga ini tidak terdengar bodoh: /[]+/

nl-x
sumber
Nggak. Bukan regex yang valid.
The Guy with The Hat
@RyanCarlson Itu sah dan sah ... Setidaknya di Ecmascript.
nl-x
-1
/$^/

Suatu hal yang berakhir sebelum dimulai ...

simon
sumber
7
Cocok dengan string kosong (dalam beberapa implementasi RE, anyways).
Josh Caswell
1
Implementasi Anda rusak :)
simon
2
Lebih baik beri tahu Guido .
Josh Caswell
7
Lebih penting lagi, seperti Ben Jackson menunjukkan , di Perl, di mana tidak cocok "", itu tidak cocok dengan string yang berisi dua karakter literal: "$^".
Josh Caswell
+1 Saya hanya ingin memposting yang sama! @Josh, ini berfungsi di PERL, dan tidak cocok dengan string kosong! Komentar Ben rusak, saya membalasnya.
Tomas