Espressione regolare ineguagliabile più breve


59

La tua missione è scrivere l'espressione regolare valida più breve che nessuna stringa può eguagliare, stringa vuota inclusa.

Le presentazioni devono avere questo modulo ("notazione letterale"):

/pattern/optional-flags

Vince regexp più breve. La dimensione di regexp è contata in caratteri. (compresi barre e flag)

Spiega come funziona il tuo regexp (se non è banale)

Grazie e buon divertimento!


Ciò ha ispirato una mia domanda. Aspetterò qualche giorno però. Non voglio che 2 domande regex siano attive contemporaneamente
Cruncher

13
"Valido" in base a quale implementazione? Ho appena trovato uno divertente con cui Perl sta bene (e questo è valido secondo l'unica grammatica RE che posso trovare , ma quel grep e il modulo re di Python rifiutano.
Josh Caswell

1
Sì, quale dialetto / i di regex? Ce ne sono molti diversi.
hippietrail,

1
E i nomi dei presidenti? xkcd.com/1313
Carl Witthoft

@CarlWitthoft Devi essere un programma per partecipare a quel concorso: codegolf.stackexchange.com/q/17718/2180
stand dal

Risposte:


53

6 caratteri

Seguendo le risposte di primo e Peter Taylor, e un suggerimento da man perlre:

/(?!)/

Questa regex compatibile perl corrisponde a una stringa vuota che non è seguita da un'altra stringa vuota.


+1 - Questa è probabilmente la risposta più breve che è ampiamente portatile (insieme a /x\by/, ma se mai dovessi effettivamente usare un regex come questo - per qualsiasi motivo - allora questa risposta è anche la più chiara)
Martin Ender

@ m.buettner: grazie. Il primo /(*FAIL)/è probabilmente più chiaro, però. (E in realtà l'ha man perlredato via menzionando che il mio si espande effettivamente al suo interno.)
Nate Eldredge,

/(*FAIL)/non è così portatile però. E anche in Perl, penso che sia una caratteristica più oscura di uno sguardo negativo.
Martin Ender,

3
Ottieni quasi tutti i gusti popolari (ispirati al Perl) oggi, mentre non ho mai visto questi verbi di controllo da nessuna parte tranne che in Perl.
Martin Ender,

1
In effetti, la documentazione Perl (e -Mre=debug) afferma che (?!)è ottimizzato (*FAIL)dall'ottimizzatore regex Perl ( OPFAILsecondo -Mre=debug). Inoltre, non credo di aver visto (*FAIL)al di fuori di Perl 5 (e Perl 6, dove si chiama <!>).
Konrad Borowski,

39

8 caratteri

/(?=a)b/

Abbiamo bisogno di una stringa contenente un carattere che sia entrambi ae b, che è ovviamente impossibile.


19
/(?!x)x/sembra ancora più impossibile ;-)
Howard,

@PeterTaylor dove?
o0 '.

@Lohoris, dove cosa?
Peter Taylor,

@PeterTaylor dove ha messo quelle assurde regole di cui parli, non sono riuscito a trovarle.
o0 '.

7
ragazzi, scusate il conteggio che ho scelto, ho pensato che sarebbe stato più semplice includere le barre a causa delle bandiere opzionali che potrebbero seguirle.
xem

31

5 caratteri

A differenza di tutti coloro che abusano $e ^... questo in realtà funziona in Perl:

/V\A/

\A corrisponde all'inizio della stringa.


Funziona ^anche con .
Tomas,


28

8 caratteri

/\w\b\w/

Un limite di parole ( \b) circondato da caratteri 'word' ( \w- uno di [_a-zA-Z0-9]). È ineguagliabile poiché uno dei caratteri che precedono o seguono un limite di parole deve essere un carattere non "parola".

A proposito: questo è simile all'espressione ineguagliabile

/\W\b\W/

dove \Wsignifica carattere non "parola".


Questi sono 8 personaggi secondo le regole della competizione, perché /contano le barre avvolgenti . Vedi la voce OP, per esempio . È un'ottima voce, però!
Josh Caswell,

Potrebbe anche essere un vincitore (o legato alla voce di Peter Taylor ), dati i problemi legati all'implementazione con alcune delle voci più brevi!
Josh Caswell

Molto elegante! Pensavo ci dovesse essere qualcosa del genere!
Tomas,

22

4 caratteri

/$a/

cerca una "a" dopo la fine della stringa.

o

/a^/

cerca a prima dell'inizio della stringa.


20
Perché pubblicare la domanda se sai che esiste una soluzione a due caratteri?
Peter Taylor,

3
@Howard: corrisponde a una stringa vuota: jsfiddle.net/RjLxJ
ProgramFOX

10
Perché trovo sempre questi problemi dopo aver fornito una soluzione imbattibile :(
Cruncher

43
-1: Mettere ^e $in posizioni "illegali" fa sì che vengano trattati come normali personaggi. Il tuo primo esempio corrisponde al letterale $ain sede probabilmente ad altri programmi.
Ben Jackson,

2
@Ben Jackson, questo non è vero per gli ERE POSIX. Prova echo 'a^b' | grep 'a^b'vs. echo 'a^b' | grep -E 'a^b'. Check out 9.4.9 ERE Expression Anchoring
laindir

21

5 caratteri

/$.^/

/$^/ corrisponderà a una stringa vuota, mentre non è richiesto un carattere in mezzo.


6
Questo purtroppo corrisponde "$a^"(o qualcosa al posto del 'a') in Perl ( e forse sed ). Comunque bello, comunque!
Josh Caswell,

@JoshCaswell: immagino che perl possa interpretare $.come l'attuale variabile del numero di riga. Quale potrebbe essere vuoto, nel qual caso sarà /^/.
MvG

Un carattere "tra" significa solo una stringa di un carattere.
jwg

3
@jwg notate lo scambio ^e$
mniip

Ho provato il modello '$^'con grep, ma sfortunatamente corrispondeva alla stringa '$^'. Smartass grep.
joeytwiddle,

19

9 caratteri

Non sono sicuro, ma /[^\S\s]/dovrebbe essere ineguagliabile poiché non significa alcun personaggio, ma almeno uno di loro.


Non hai bisogno del +.
Peter Taylor,

10
/ [^ \ S \ s] / = 9 caratteri
xem

19

6 caratteri

Penso che questa regex che ho creato funzionerà:

/\b\B/

Corrisponde a una parola limite ( \b) che non è una parola limite ( \B). Quali sono le impos: devo davvero spiegartelo?


questo non cerca un limite di parole seguito da un limite di non parole?
Grexter89,

1
@ grexter89 Sì, ma non possono avere caratteri in mezzo. cioè il confine e il non confine devono occupare lo stesso spazio.
The Guy with The Hat

2
Mi piace questa. Buona pesca.
primo

18

4 caratteri

(Solo sapore ECMAScript)

/[]/

In altri gusti questa non è una classe di caratteri valida ( ]sarebbe considerata un carattere nella classe, quindi l'espressione non è valida, perché la classe non è mai chiusa), ma lo standard ECMAScript accetta classi di caratteri vuote. Dal momento che è una classe deve corrispondere a un personaggio (quindi le stringhe vuote non corrispondono), ma poiché non è incluso un singolo carattere, neanche un personaggio reale corrisponderà.


Questo non corrisponderebbe a una stringa vuota anche se dici che deve corrispondere a un personaggio? O pensi che questo è illegale: /[]{0}/. (Ps. Sebbene la mia risposta assomigli in parte alla tua, in realtà ho letto la tua dopo aver scritto la mia.)
nl-x

@ nl-x incolla questo nella console del browser: /[]/.test(""). restituisce false. una classe di caratteri non può mai abbinare una stringa vuota, anche se non contiene caratteri (immagino che siano implementati come "SE il carattere successivo nella stringa è uno di quelli elencati, match; ELSE fail"). /[]{0}/è legale (in ECMAScript) e corrisponde alla stringa vuota ... tuttavia, non sono sicuro di quanto sia rilevante per la mia risposta.
Martin Ender,

Fallisce in Ruby 2.0
Nakilon il

@Nakilon ovviamente lo fa. Ruby non implementa il sapore ECMAScript.
Martin Ender,

15

6 caratteri

/b++b/

Il quantificatore possessivo cerca quante più b possibili, quindi 1 in più. 6 caratteri ma punti per la simmetria?


Huh ... Ho appena imparato una nuova funzione. Apparentemente, le mie capacità di regex sono molto obsolete. Grazie e +1.
Ilmari Karonen,

8

6 caratteri

/(\1)/

Non un vincitore, ma ho pensato che fosse divertente. grep e Python sono entrambi contrari a questo, ma Perl sembra a posto.

Sembra essere molto dipendente dall'implementazione (il che non sorprende, data la sua stranezza). Bob riporta di seguito che corrisponde a qualsiasi cosa nel motore regex di JavaScript.


Il motore regex di .NET sembra accettarlo.
Bob

E corrisponde sempre (una stringa vuota) qualunque sia l'input su JS
Bob

8

Forse un po 'di barare, ma ...

\0

... è ineguagliabile in regex POSIX praticamente in tutte le implementazioni, se non in tutte. BASIC RE e EXTENDED RE, pari.

E POSIX RE non ha bisogno di quelle fastidiose barre e bandiere di PCRE.


+1 Buono !! Sfortunatamente, la suola 0non funziona in PERL. "0"=~0è vero ...
Tomas,

unico \0ITYM? Sì, la maggior parte delle implementazioni perlre (1) e PCRE non usano stringhe C ma buffer a dimensioni limitate, in cui questo trucco non funzionerà, ma la maggior parte delle implementazioni POSIX RE funzionano su stringhe C.
mirabilos,

5

5 caratteri

/^.^/

Trova la stringa che inizia con un singolo carattere prima dell'inizio della stringa.


6
".^"
Corrisponde

@boothby: in quale lingua corrisponde? in Python no. re.findall(r'^.^', '.^', re.DEBUG)
P̲̳x͓L̳

8
+1 per l'utilizzo dell'operatore manga (vedi stackoverflow.com/questions/3618340/… )
prototipo

@boothby ^e .sono metacaratteri non letterali, che devono essere evasi
P̲̳x͓L̳

1
È rotto in Perl. Questa domanda avrebbe davvero dovuto stabilire alcune regole di base sul linguaggio.
stand dal

5

4 caratteri:

/.^/

Funziona con GNU grep 2.5.1 ed egrep.


/.^/= 4 caratteri.
Alexey Popkov,

Perché hai bisogno del //? quelli non sono richiesti ovunque ;-)
RSFalcon7

Le barre avvolgenti /contano, vedere la domanda originale ("comprese barre e bandierine") e la voce del PO .
Alexey Popkov,

giusto! Mi manca leggere :(
RSFalcon7

No, per lo stesso motivo di quello seguente: In realtà, “^” è speciale solo all'inizio del modello. Qualsiasi “^” dopo qualsiasi altra cosa non ha bisogno di essere evitato, quindi questa risposta è sbagliata.
mirabilos,

4

Perl 6 (5 caratteri)

/<!>/

Abuso della regola di Sorta (perché le regex di Perl 6 sono diverse e incompatibili con le regex stardard in base alla progettazione), ma non mi interessa. <!>regola informa Perl 6 che la regex non corrisponde.


4

6 byte

/(*F)/

Abbreviazione di (*FAIL), supportata da motori regex compatibili perl. Grazie a @HamZa per averlo segnalato.

9 byte

/(*FAIL)/

Dovrebbe funzionare con qualsiasi motore regex che supporti i verbi. Non sono convinto che questo debba davvero essere ulteriormente giocato a golf.


1
Come funziona?
stand del

@boothby (*FAIL)è un verbo che fallisce sempre.
primo

@primo potresti semplicemente usare /(*F)/:)
HamZa

4

4 caratteri

/$./

Ha bisogno di qualsiasi carattere dopo la fine della stringa


Analogamente agli altri due, $è speciale solo alla fine del modello.
mirabilos,

3

4 caratteri con barre 2 senza

Nel motore regex del linguaggio TXR, una classe di caratteri vuota []non corrisponde a nessun carattere e quindi nessuna stringa. Si comporta in questo modo perché la classe di caratteri richiede una corrispondenza di carattere e quando è vuota specifica che nessun personaggio può soddisfarla.

Un altro modo è quello di invertire il "insieme di tutte le stringhe tra vuoto" regex /.*/utilizzando l'operatore di complemento: /~.*/. Il complemento di quell'insieme non contiene affatto stringhe, quindi non può eguagliare nulla.

Tutto questo è documentato nella pagina man:

   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".

Le barre non fanno parte della sintassi regex di per sé; sono solo punteggiatura che delimita le regex nella notazione dell'espressione S. Testimone:

# 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

grazie per la risposta e scusate ancora per il conteggio delle barre. Ho pensato che sarebbe stato più facile includerli se le persone avessero usato le bandiere.
xem,

1

6 caratteri

(o 4, a seconda di come lo guardi)

/{,0}/

Fallisce in Ruby 2.0
Nakilon il

In quali implementazioni regex questo non dà un errore?
Peter Taylor,

L'ho provato solo usando preg_match di PHP.
Tercy,

1

Questo è un regex a 5 caratteri.

/[]+/

Corrisponde a un gruppo vuoto 1 o più volte.

MODIFICARE:

Rimossa la mia risposta per altri gusti:

/.{-1}/

Tutto ciò che non è un numero all'interno di {} corrisponderà al testo.

Questo corrisponderà a ". {- 1}"


Si noti che funziona solo con il sapore ECMAScript. Nella maggior parte (tutti?) Altri non è un'espressione valida.
Martin Ender,

Non è invalido?
Wasi,

@Wasi non nei gusti conformi a ECMAScript
Martin Ender


-1
/$^/

Una cosa che finisce prima che abbia inizio ...


7
Corrisponde alla stringa vuota (in alcune implementazioni RE, comunque).
Josh Caswell,

1
L'implementazione non funziona :)
simon,

2
Meglio far sapere a Guido .
Josh Caswell,

7
Ancora più importante, come Ben Jackson ha sottolineato , in Perl, in cui non corrisponde "", che non corrisponde a una stringa contenente quei due caratteri letterali: "$^".
Josh Caswell,

+1 Volevo solo pubblicare lo stesso! @Josh, funziona in PERL e non corrisponde a una stringa vuota! Il commento di Ben è rotto, gli ho risposto.
Tomas,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.