La plus courte expression régulière inégalée

59

Votre mission est d'écrire l'expression régulière la plus courte valide à laquelle aucune chaîne ne peut correspondre, chaîne vide incluse.

Les soumissions doivent avoir cette forme ("notation littérale"):

/pattern/optional-flags

La plus courte expression rationnelle gagne. La taille de l'expression rationnelle est comptée en caractères. (y compris les barres obliques et les drapeaux)

S'il vous plaît expliquer comment votre expression rationnelle fonctionne (si ce n'est pas trivial)

Merci et amusez-vous!

xem
la source
Cela m'a inspiré une question. Je vais cependant attendre quelques jours. Vous ne voulez pas que deux questions de regex soient actives en même temps
Cruncher le
13
"Valide" selon quelle implémentation? Je viens de trouver une version amusante avec laquelle Perl est d'accord (et c'est valable selon la seule grammaire RE que je puisse trouver , mais ce module de grep et de Python refuse.
Josh Caswell, le
1
Oui, quel dialecte de regex? Il y en a beaucoup beaucoup de différents.
hippietrail
1
Mais qu'en est-il des noms des présidents? xkcd.com/1313
Carl Witthoft
@CarlWitthoft Vous devez être un programme pour participer à ce concours: codegolf.stackexchange.com/q/17718/2180
rendez-vous le

Réponses:

53

6 caractères

Après les réponses de primo et Peter Taylor, et un indice tiré de man perlre:

/(?!)/

Cette expression rationnelle compatible Perl correspond à une chaîne vide qui n'est pas suivie d'une autre chaîne vide.

Nate Eldredge
la source
+1 - C'est probablement la réponse la plus courte qui soit largement portable (avec /x\by/, mais si jamais je devais réellement utiliser une regex comme celle-ci - pour une raison quelconque - cette réponse serait aussi la plus claire)
Martin Ender
@ m.buettner: Merci. Le primo /(*FAIL)/est probablement plus clair, cependant. (Et en man perlrefait, il a donné cela en mentionnant que le mien s'étend réellement à son interne.)
Nate Eldredge le
/(*FAIL)/n'est pas aussi portable cependant. Et même en Perl, je pense que c'est une caractéristique plus obscure qu'un aspect négatif.
Martin Ender
3
Vous obtenez des regards dans presque toutes les saveurs populaires (inspirées par Perl) aujourd'hui, alors que je n'ai jamais vu ces verbes de contrôle ailleurs que dans Perl.
Martin Ender
1
En fait, la documentation Perl (et -Mre=debug) indique que cela (?!)est optimisé (*FAIL)par Perl regex optimizer ( OPFAILselon -Mre=debug). De plus, je ne pense pas avoir vu à l' (*FAIL)extérieur de Perl 5 (et Perl 6, où il s'appelle <!>).
Konrad Borowski
39

8 caractères

/(?=a)b/

Nous avons besoin d'une chaîne contenant un caractère qui est à la fois aet b, ce qui est évidemment impossible.

Peter Taylor
la source
19
/(?!x)x/semble encore plus impossible ;-)
Howard
@PeterTaylor où?
o0 '.
@ Lohoris, où quoi?
Peter Taylor
@ PeterTaylor, où a-t-il mis ces règles absurdes dont vous parlez, je ne les ai pas trouvées.
o0 '.
7
les gars, désolé pour le comptage que j'ai choisi, j'ai pensé qu'il serait plus simple d'inclure des barres obliques à cause des drapeaux facultatifs qui pourraient les suivre.
xem
31

5 caractères

Contrairement à tous ceux qui abusent $et ^... cela fonctionne en Perl:

/V\A/

\A correspond au début de la chaîne.

boothby
la source
Cela fonctionne ^aussi.
Tomas
28

8 personnages

/\w\b\w/

Une limite de mot ( \b) entourée de caractères 'mot' ( \wun des [_a-zA-Z0-9]). Il est impossible à joindre car l'un des caractères précédant ou suivant une limite de mot doit être un caractère non 'mot'.

À propos: cela ressemble à l'expression inégalable

/\W\b\W/

\Wsignifie non-mot 'caractère'.

Sven Hohenstein
la source
Il s’agit de 8 personnages selon les règles de la compétition, car les slash d’emballage /comptent. Voir l'entrée de OP, par exemple . C'est une excellente entrée, cependant!
Josh Caswell
Cela pourrait également être un gagnant (ou à égalité avec l'entrée de Peter Taylor ), étant donné les problèmes liés à la mise en œuvre avec certaines des entrées les plus courtes!
Josh Caswell
Très élégant! Je pensais qu'il devait y avoir quelque chose comme ça!
Tomas
22

4 caractères

/$a/

recherche un "a" après la fin de la chaîne.

ou

/a^/

recherche avant le début de la chaîne.

xem
la source
20
Pourquoi poster la question si vous savez qu'il existe une solution à deux caractères?
Peter Taylor
3
@Howard: Cela correspond à une chaîne vide: jsfiddle.net/RjLxJ
ProgramFOX le
10
Pourquoi est-ce que je trouve toujours ces problèmes après avoir trouvé une solution imbattable :(
Cruncher
43
-1: Mettre ^et $dans des positions "illégales" les fait simplement traiter comme des personnages ordinaires. Votre premier exemple correspond au littéral $ade sedet probablement à d’autres programmes.
Ben Jackson
2
@ Ben Jackson, ce n'est pas vrai pour les ERE POSIX. Essayez echo 'a^b' | grep 'a^b'contre echo 'a^b' | grep -E 'a^b'. Découvrez 9.4.9 ERE Ancrage Expression
laindir
21

5 personnages

/$.^/

/$^/ correspondra à une chaîne vide, alors qu'exiger un caractère entre les deux ne le sera pas.

Brian Glaz
la source
6
Cela correspond malheureusement "$a^"(ou quoi que ce soit à la place de 'a') en Perl ( et peut-être sed ). Encore une belle, cependant!
Josh Caswell
@ JoshCaswell: Je suppose que Perl pourrait être interprété $.comme la variable de numéro de ligne actuelle. Ce qui pourrait être vide, auquel cas ce sera le cas /^/.
MvG
Un caractère 'entre' signifie simplement une chaîne d'un caractère.
Jwg
3
@jwg remarque le swap ^et$
mniip
J'ai essayé le motif '$^'avec grep, mais malheureusement, il correspondait à la chaîne '$^'. Smartass grep.
joeytwiddle
19

9 caractères

Je ne suis pas sûr, mais je /[^\S\s]/devrais être inégalable, car cela ne signifie aucun personnage, mais au moins un d'entre eux.

utilisateur14325
la source
Vous n'avez pas besoin du +.
Peter Taylor
10
/ [^ \ S \ s] / = 9 caractères
xem
19

6 personnages

Je pense que cette regex que j'ai faite va marcher:

/\b\B/

Il correspond à une limite de mot ( \b) qui n'est pas une limite de mot ( \B). Quel est l'impost - dois-je vraiment vous l'expliquer?

Le gars avec le chapeau
la source
Celui-ci ne recherche-t-il pas une limite de mot suivie d'une limite de non-mot?
grexter89
1
@ grexter89 Oui, mais ils ne peuvent contenir aucun caractère entre eux. C'est-à-dire que la limite et la non-limite doivent occuper le même espace.
Le gars avec le chapeau
2
J'aime celui la. Bonne prise.
Primo
18

4 personnages

(Version ECMAScript uniquement)

/[]/

Dans d'autres variantes, il ne s'agit pas d'une classe de caractères valide ( ]considérée comme un caractère de la classe, l'expression n'est donc pas valide car la classe n'est jamais fermée), mais le standard ECMAScript accepte les classes de caractères vides. Puisqu'il s'agit d'une classe, il doit correspondre à un caractère (donc les chaînes vides ne correspondent pas), mais comme aucun caractère n'est inclus, aucun caractère réel ne correspond non plus.

Martin Ender
la source
Cela ne correspond-il pas à une chaîne vide même si vous dites qu'il doit correspondre à un caractère? Ou pensez - vous que cela est illégal: /[]{0}/. (Ps. Bien que ma propre réponse ressemble en partie à la vôtre, j'ai en fait lu la vôtre après avoir écrit la mienne.)
nl-x
@ nl-x coller dans la console de votre navigateur: /[]/.test(""). ça retourne faux. une classe de caractères ne peut jamais correspondre à une chaîne vide, même si elle ne contient pas de caractères (j'imagine qu'elles sont implémentées comme "SI le prochain caractère de la chaîne est l'un de ceux répertoriés, match; ELSE fail"). /[]{0}/est légal (dans ECMAScript) et correspond à la chaîne vide ... Cependant, je ne suis pas sûr de savoir en quoi cela est pertinent pour ma réponse.
Martin Ender
Échoue dans Ruby 2.0
Nakilon
@Nakilon bien sûr que c'est le cas. Ruby n'implémente pas la version ECMAScript.
Martin Ender
15

6 caractères

/b++b/

Le quantificateur possessif cherche autant de b's que possible, puis 1 de plus. 6 caractères mais des points pour la symétrie?

VBCPP
la source
Hein ... Je viens d'apprendre une nouvelle fonctionnalité. Apparemment, mes compétences de regex sont mal dépassées. Merci et +1.
Ilmari Karonen
8

6 personnages

/(\1)/

Pas un gagnant, mais j'ai pensé que c'était amusant. grep et Python sont tous les deux sur ce coup-là, mais Perl semble être d'accord avec ça.

Cela semble être très dépendant de la mise en œuvre (ce qui n’est guère surprenant compte tenu de son étrangeté). Bob indique ci-dessous qu'il correspond à quoi que ce soit dans le moteur de regex de JavaScript.

Josh Caswell
la source
Le moteur de regex de .NET semble l'accepter.
Bob
Et cela correspond toujours (une chaîne vide) quelle que soit l'entrée sur JS
Bob
8

Peut-être un peu de triche, mais…

\0

… Est imbattable dans les regex POSIX dans pratiquement toutes les implémentations, si ce n'est toutes. BASIC RE et EXTENDED RE, même.

Et POSIX RE n’a pas besoin de ces barres obliques ni de ces drapeaux.

mirabilos
la source
+1 bien !! Malheureusement, la semelle 0ne fonctionne pas dans PERL. "0"=~0est vrai ...
Tomas
seul \0ITYM? Oui, la plupart des implémentations perlre (1) et PCRE n'utilisent pas de chaînes C, mais des tampons limités en taille, dans lesquels cette astuce ne fonctionnera pas, mais la plupart des implémentations POSIX RE fonctionnent sur des chaînes C.
mirabilos
5

5 caractères

/^.^/

Correspond à la chaîne qui commence par n'importe quel caractère avant le début de la chaîne.

P̲̳x͓L̳
la source
6
".^"
Correspond
@boothby: dans quelle langue les correspondances? en Python pas. re.findall(r'^.^', '.^', re.DEBUG)
P̲̳x͓L̳
8
+1 pour utiliser l'opérateur manga (voir stackoverflow.com/questions/3618340/… )
prototype
@boothby ^et .sont des métacaractères non littérales, qui doivent être
évitées
1
C'est cassé en Perl. Cette question aurait vraiment dû fixer des règles de base concernant la langue.
Boothby
5

4 caractères:

/.^/

Fonctionne avec GNU grep 2.5.1 et egrep.

RSFalcon7
la source
/.^/= 4 caractères.
Alexey Popkov
Pourquoi avez-vous besoin de //? ceux-ci ne sont pas nécessaires partout ;-)
RSFalcon7
Les barres englobantes /comptent, voir la question initiale ("y compris les barres obliques et les drapeaux") et l' entrée du PO .
Alexey Popkov
droite! Je manque de lire :(
RSFalcon7
Non, pour la même raison que celle ci-dessous: En fait, “^” n’est spécial que si il se trouve au début du motif. Tout «^» après quoi que ce soit d'autre n'a pas besoin d'être échappé, alors cette réponse est fausse.
mirabilos
4

Perl 6 (5 caractères)

/<!>/

Un peu abusé des règles (parce que les expressions rationnelles Perl 6 sont différentes et incompatibles avec les expressions rationnelles stardard de par leur conception), mais je m'en fiche. <!>La règle informe Perl 6 que la regex ne correspond pas.

Konrad Borowski
la source
4

6 octets

/(*F)/

Abréviation de (*FAIL), prise en charge par les moteurs de regex compatibles perl. Merci à @HamZa pour l'avoir signalé.

9 octets

/(*FAIL)/

Devrait fonctionner avec n’importe quel moteur de regex prenant en charge les verbes. Je ne suis pas convaincu qu'il faille jouer davantage au golf.

primo
la source
1
Comment cela marche-t-il?
Boothby
@boothby (*FAIL)est un verbe qui échoue toujours.
primo
@primo vous pouvez simplement utiliser /(*F)/:)
HamZa
4

4 caractères

/$./

Nécessite n'importe quel caractère après la fin de la chaîne

C0de Freak
la source
De la même manière que les deux autres, $n’est spécial qu’à la fin du motif.
mirabilos
3

4 caractères avec barres obliques 2 sans

Dans le moteur de regex du langage TXR, une classe de caractères vide []ne correspond à aucun caractère, et donc aucune chaîne. Il se comporte de cette manière car la classe de caractères nécessite une correspondance de caractère et, lorsqu'elle est vide, elle spécifie qu'aucun caractère ne peut la satisfaire.

Une autre façon est d'inverser le « ensemble de toutes les chaînes , y compris vide » regex en /.*/utilisant l'opérateur complément: /~.*/. Le complément de cet ensemble ne contient aucune chaîne et ne peut donc rien correspondre.

Tout cela est documenté dans la page de manuel:

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

Les barres obliques ne font pas partie de la syntaxe regex en soi; ce ne sont que des ponctuations qui délimitent les expressions rationnelles dans la notation S-expression. Témoin:

# 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
la source
merci pour votre réponse et encore désolé pour le comptage des barres obliques. J'ai pensé qu'il serait plus facile de les inclure si les gens utilisaient des drapeaux.
xem
1

6 caractères

(ou 4, selon votre point de vue)

/{,0}/
Tercy
la source
Échoue dans Ruby 2.0
Nakilon
Dans quelles implémentations de regex cela ne donne-t-il pas une erreur?
Peter Taylor
Je l'ai seulement testé en utilisant preg_match de PHP.
Tercy
1

C'est un regex à 5 caractères.

/[]+/

Il correspond à un groupe vide une ou plusieurs fois.

MODIFIER:

Suppression de ma réponse pour d'autres saveurs:

/.{-1}/

Tout ce qui n’est pas un nombre à l’intérieur de {} correspondra au texte.

Celui-ci correspondra à ". {- 1}"

Ismael Miguel
la source
Notez que cela ne fonctionne que dans la version ECMAScript. Dans la plupart (tous?) Les autres, ce n'est pas une expression valide.
Martin Ender
N'est-ce pas invalide?
Wasi
@Wasi pas dans les saveurs conformes ECMAScript
Martin Ender
0

5 personnages

J'espère que cela ne semble pas stupide: /[]+/

nl-x
la source
Nan. Pas une regex valide.
Le gars avec le chapeau
@RyanCarlson C'est valide et légal ... Au moins dans Ecmascript.
nl-x
-1
/$^/

Une chose qui se termine avant même d'avoir commencé ...

Simon
la source
7
Correspond à la chaîne vide (de toute façon dans certaines implémentations de RE).
Josh Caswell
1
Votre implémentation est en panne :)
simon
2
Mieux vaut prévenir Guido .
Josh Caswell
7
Plus important encore , comme Ben Jackson a fait remarquer , en Perl, où il ne correspond pas "", il ne correspond une chaîne contenant ces deux caractères littéraux: "$^".
Josh Caswell
+1 je voulais juste poster le même! @ Josh, cela fonctionne dans PERL et ne correspond pas à une chaîne vide! Le commentaire de Ben est cassé, j'y ai répondu.
Tomas