Sapore PCRE, 261 289 210 184 127 109 71 53 51 44 40 byte
Sì, è possibile!
<^<()(?R){2}>\z|\1\Q^<()(?R){2}>\z|\1\Q>
Provalo qui. (Ma /
si dimostra che è il delimitatore su Regex101.)
Si prega di astenersi dal fare modifiche non necessarie (aggiornamenti) sulla pagina Regex101. Se la tua modifica in realtà non comporta il miglioramento, il tentativo o il test di questa regex, puoi forkarla o crearne di nuovi dalla loro homepage .
La versione funziona più correttamente su Regex101 (44 byte):
/^\/()(?R){2}\/\z|\1\Q^\/()(?R){2}\/\z|\1\Q/
Provalo qui.
Questo è molto più semplice rispetto alla versione originale e funziona più come un quine tradizionale. Cerca di definire una stringa senza usarla e di usarla in un posto diverso. Quindi può essere posizionato molto vicino a un'estremità della regex, per ridurre il numero di caratteri che necessitano di più caratteri per definire il modello di corrispondenza e ripetersi più volte.
spiegazioni:
\Q^\/()(?R){2}\/\z|\1\Q
corrisponde alla stringa ^\/()(?R){2}\/\z|\1\Q
. Questo utilizza una stranezza che \Q...\E
non deve essere chiusa e funzionano i delimitatori senza escape \Q
. Ciò ha fatto funzionare alcune versioni precedenti solo su Regex101 e non localmente. Ma fortunatamente l'ultima versione ha funzionato, e ho usato qualche altro byte usando questo.
\1
prima che \Q
corrisponda al gruppo catturato 1. Poiché il gruppo 1 non esiste in questa opzione, può corrispondere solo nelle chiamate ricorsive. Nelle chiamate ricorsive corrisponde a stringhe vuote.
(?R){2}
chiama ricorsivamente l'intero regex due volte, che corrisponde ^\/()(?R){2}\/\z|\1\Q
per ogni volta.
()
non fa altro che catturare una stringa vuota nel gruppo 1, che abilita l'altra opzione nelle chiamate ricorsive.
^\/()(?R){2}\/\z
corrispondenze (?R){2}
con delimitatori aggiunti, dall'inizio alla fine. Il \/
prima delle chiamate ricorsive si è anche assicurato che questa stessa opzione non corrispondesse alle chiamate ricorsive, perché non sarà all'inizio della stringa.
51 byte con chiuso \Q...\E
:
/\QE\1|^\/(\\)Q(?R){2}z\/\E\1|^\/(\\)Q(?R){2}z\/\z/
Provalo qui.
Versione originale, 188 byte
Grazie a Martin Büttner per aver giocato a golf a circa 100 byte!
/^(?=.{173}\Q\2\)){2}.{11}$\E\/\z)((?=(.2.|))\2\/\2\^\2\(\2\?=\2\.\2\{173}\2\\Q\2\\2\2\\\2\)\2\)\2\{2}\2\.\2\{11}\2\$\2\\E\2\\\2\/\2\\z\2\)\2\(\2\(\2\?=\2\(\2\.2\2\.\2\|\2\)\2\)){2}.{11}$/
Provalo qui.
O 210 byte senza \Q...\E
:
/^(?=.{194}\\2\\.\)\{2}\.\{12}\$\/D$)((?=(.2.|))\2\/\2\^\2\(\2\?=\2\.\2\{194}\2\\\2\\2\2\\\2\\\2\.\2\\\2\)\2\\\2\{2}\2\\\2\.\2\\\2\{12}\2\\\2\$\2\\\2\/D\2\$\2\)\2\(\2\(\2\?=\2\(\2\.2\2\.\2\|\2\)\2\)){2}.{12}$/D
Provalo qui.
Versione estesa:
/^(?=.{173}\Q\2\)){2}.{11}$\E\/\z) # Match things near the end.
((?=(.2.|)) # Capture an empty string or \2\ into group 2.
\2\/\2\^\2\(\2\?=\2\.\2\{173}\2\\Q\2\\2\2\\\2\)\2\)\2\{2}\2\.
\2\{11}\2\$\2\\E\2\\\2\/\2\\z\2\) # 1st line escaped.
\2\(\2\(\2\?=\2\(\2\.2\2\.\2\|\2\)\2\) # 2nd line escaped.
){2}
.{11}$/x
Le estensioni come (?=
e \1
hanno reso le cosiddette espressioni "regolari" non più regolari, il che rende anche possibili le quine. Il backreference non è regolare, ma lo è lookahead.
Spiegazione:
- Uso
\2\
al posto di \
per sfuggire a personaggi speciali. Se \2
corrisponde alla stringa vuota, \2\x
(dove x
è un carattere speciale) corrisponde alla x
stessa. Se \2
corrisponde \2\
, \2\x
corrisponde a quello evaso. \2
nelle due partite del gruppo 1 può essere diverso in regex. Nella prima volta \2
dovrebbe corrispondere alla stringa vuota e la seconda volta \2\
.
\Q\2\)){2}.{11}$\E\/\z
(riga 1) corrisponde a 15 caratteri dalla fine. E .{11}$
(riga 7) corrisponde a 11 caratteri dalla fine (o prima di una nuova riga finale). Quindi il modello appena prima del secondo motivo deve corrispondere ai primi 4 o 3 caratteri nel primo motivo, quindi \2\.\2\|\2\)\2\)
deve corrispondere a ...\2\)
o ...\2\
. Non ci può essere una nuova riga finale perché dovrebbe essere l'ultimo carattere )
. E il testo corrispondente non ne contiene un altro )
prima di quello più a destra, quindi tutti gli altri caratteri devono essere nel \2
. \2
è definito come (.2.|)
, quindi può essere solo \2\
.
- La prima riga fa sì che l'intera espressione corrisponda esattamente a 188 caratteri poiché tutto ha una lunghezza fissa. Le due volte del gruppo 1 corrispondono a 45 * 2 caratteri più 29 volte
\2
. E le cose dopo il gruppo 1 corrispondono a 11 caratteri. Quindi la lunghezza totale delle due volte \2
deve essere esattamente di 3 caratteri. Sapendo \2
per la seconda volta che è lungo 3 caratteri, deve essere vuoto per la prima volta.
- Tutto tranne il lookahead e
\2
sono letterali nel gruppo 1. Con le due volte \2
conosciute e gli ultimi pochi caratteri noti dalla prima riga, questa regex corrisponde esattamente a una stringa.
- Martin Büttner ha avuto l'idea di usare lookahead per catturare il gruppo 2 e farlo sovrapporre con la parte quine. Ciò ha rimosso i personaggi non sfuggiti nel modo normale tra le due volte del gruppo 1, e ha aiutato a evitare lo schema per abbinarli nella mia versione originale e ha semplificato molto la regex.
Regex senza ricorsioni o riferimenti secondari, 85 byte
Qualcuno potrebbe obiettare che le espressioni con ricorsioni o riferimenti arretrati non sono vere espressioni "regolari". Ma le espressioni con solo un lookahead possono ancora corrispondere solo alle lingue normali, sebbene possano essere molto più lunghe se espresse dalle espressioni regolari tradizionali.
/(?=.*(\QE\\){2}z\/\z)^\/\(\?\=\.\*\(\\Q.{76}\E\\){2}z\/\z)^\/\(\?\=\.\*\(\\Q.{76}\z/
Provalo qui.
610 byte senza \Q...\E
(da giocare a golf):
/^(?=.{610}$)(?=.{71}(\(\.\{8\}\)\?\\.[^(]*){57}\)\{2\}\.\{12\}\$\/D$)((.{8})?\/(.{8})?\^(.{8})?\((.{8})?\?=(.{8})?\.(.{8})?\{610(.{8})?\}(.{8})?\$(.{8})?\)(.{8})?\((.{8})?\?=(.{8})?\.(.{8})?\{71(.{8})?\}(.{8})?\((.{8})?\\(.{8})?\((.{8})?\\(.{8})?\.(.{8})?\\(.{8})?\{8(.{8})?\\(.{8})?\}(.{8})?\\(.{8})?\)(.{8})?\\(.{8})?\?(.{8})?\\(.{8})?\\(.{8})?\.(.{8})?\[(.{8})?\^(.{8})?\((.{8})?\](.{8})?\*(.{8})?\)(.{8})?\{57(.{8})?\}(.{8})?\\(.{8})?\)(.{8})?\\(.{8})?\{2(.{8})?\\(.{8})?\}(.{8})?\\(.{8})?\.(.{8})?\\(.{8})?\{12(.{8})?\\(.{8})?\}(.{8})?\\(.{8})?\$(.{8})?\\(.{8})?\/D(.{8})?\$(.{8})?\)(.{8})?\(){2}.{12}$/D
Provalo qui.
L'idea è simile.
/^(?=.{610}$)(?=.{71}(\(\.\{8\}\)\?\\.[^(]*){57}\)\{2\}\.\{12\}\$\/D$)
((.{8})?\/(.{8})?\^(.{8})?\((.{8})?\?=(.{8})?\.(.{8})?\{610(.{8})?\}(.{8})?\$(.{8})?\)
(.{8})?\((.{8})?\?=(.{8})?\.(.{8})?\{71(.{8})?\}
(.{8})?\((.{8})?\\(.{8})?\((.{8})?\\(.{8})?\.(.{8})?\\(.{8})?\{8(.{8})?\\(.{8})?\}
(.{8})?\\(.{8})?\)(.{8})?\\(.{8})?\?(.{8})?\\(.{8})?\\
(.{8})?\.(.{8})?\[(.{8})?\^(.{8})?\((.{8})?\](.{8})?\*(.{8})?\)(.{8})?\{57(.{8})?\}
(.{8})?\\(.{8})?\)(.{8})?\\(.{8})?\{2(.{8})?\\(.{8})?\}
(.{8})?\\(.{8})?\.(.{8})?\\(.{8})?\{12(.{8})?\\(.{8})?\}
(.{8})?\\(.{8})?\$(.{8})?\\(.{8})?\/D(.{8})?\$(.{8})?\)(.{8})?\(){2}.{12}$/D
L'espressione regolare di base
Se lookahead non è permesso, il meglio che posso fare ora è:
/\\(\\\(\\\\){2}/
che corrisponde
\\(\\\(\\
Se il {m,n}
quantificatore non è consentito, è impossibile perché nulla che può corrispondere a una sola stringa può corrispondere a una stringa più lunga di se stessa. Naturalmente si può ancora inventare qualcosa di simile \q
che corrisponde solo /\q/
e dire espressioni con quel normale. Ma a quanto pare nulla di simile è supportato da importanti implementazioni.