Expresión regular más corta e inigualable

59

Su misión es escribir la expresión regular válida más corta que ninguna cadena pueda coincidir, incluida la cadena vacía.

Los envíos deben tener esta forma ("notación literal"):

/pattern/optional-flags

La expresión regular más corta gana. El tamaño de expresión regular se cuenta en caracteres. (incluyendo barras y banderas)

Por favor, explique cómo funciona su expresión regular (si no es trivial)

Gracias y diviértete!

xem
fuente
Esto inspiró una pregunta mía. Aunque voy a esperar unos días. No quiero 2 preguntas regex activas al mismo tiempo
Cruncher
13
¿"Válido" según qué implementación? Acabo de encontrar una divertida con la que Perl está de acuerdo (y eso es válido de acuerdo con la única gramática RE que puedo encontrar , pero ese grep y el módulo re de Python se niegan.
Josh Caswell
1
Sí, ¿qué dialecto (s) de expresión regular? Hay muchos muchos diferentes.
hippietrail
1
¿Pero qué hay de los nombres de los presidentes? xkcd.com/1313
Carl
@CarlWitthoft Necesitas ser un programa para participar en ese concurso: codegolf.stackexchange.com/q/17718/2180
stand

Respuestas:

53

6 caracteres

Siguiendo las respuestas de primo y Peter Taylor, y una pista de man perlre:

/(?!)/

Esta expresión regular compatible con perl coincide con una cadena vacía que no es seguida por otra cadena vacía.

Nate Eldredge
fuente
+1: esta es probablemente la respuesta más corta que es ampliamente portátil (junto con /x\by/, pero si alguna vez tuve que usar una expresión regular como esta, por alguna razón, entonces esta respuesta también es la más clara)
Martin Ender
@ m.buettner: Gracias. /(*FAIL)/sin embargo, primo es probablemente más claro. (Y en realidad man perlrelo delató al mencionar que el mío realmente se expande internamente).
Nate Eldredge
/(*FAIL)/Sin embargo, no es tan portátil. E incluso en Perl, creo que es una característica más oscura que una anticipación negativa.
Martin Ender
3
Hoy en día, obtienes búsquedas en casi todos los sabores populares (inspirados en Perl), mientras que nunca he visto estos verbos de control en ningún otro lugar que no sea Perl.
Martin Ender
1
De hecho, la documentación de Perl (y -Mre=debug) dice que (?!)está optimizado (*FAIL)por Perl regex optimizer ( OPFAILsegún -Mre=debug). Además, no creo haber visto (*FAIL)fuera de Perl 5 (y Perl 6, donde se llama <!>).
Konrad Borowski
39

8 caracteres

/(?=a)b/

Requerimos una cadena que contenga un carácter que sea ambos ay bque obviamente es imposible.

Peter Taylor
fuente
19
/(?!x)x/parece aún más imposible ;-)
Howard
@PeterTaylor ¿dónde?
o0 '.
@Lohoris, ¿dónde qué?
Peter Taylor
@PeterTaylor donde puso esas reglas absurdas de las que hablas, no pude encontrarlas.
o0 '.
77
muchachos, perdón por el conteo que elegí, pensé que sería más simple incluir barras inclinadas debido a las banderas opcionales que podrían venir después de ellos.
xem
31

5 caracteres

A diferencia de todos los que abusan $y ^... esto realmente funciona en Perl:

/V\A/

\A coincide con el comienzo de la cadena.

boothby
fuente
Funciona con ^también.
Tomás
28

8 caracteres

/\w\b\w/

Un límite de palabra ( \b) rodeado de caracteres de 'palabra' ( \w- uno de [_a-zA-Z0-9]). Es inigualable ya que uno de los caracteres que preceden o siguen a un límite de palabra debe ser un carácter que no sea 'palabra'.

Por cierto: esto es similar a la expresión inigualable

/\W\b\W/

donde \Wsignifica carácter que no es 'palabra'.

Sven Hohenstein
fuente
Estos son 8 caracteres de acuerdo con las reglas de la competencia, porque las barras oblicuas /cuentan. Ver la entrada de OP, por ejemplo . ¡Sin embargo, es una gran entrada!
Josh Caswell
¡También podría ser un ganador (o empatado con la entrada de Peter Taylor ), dados los problemas dependientes de la implementación con algunas de las entradas más cortas!
Josh Caswell
¡Muy elegante! ¡Pensé que debía haber algo como esto!
Tomás
22

4 caracteres

/$a/

busca una "a" después del final de la cadena.

o

/a^/

busca un antes del comienzo de la cadena.

xem
fuente
20
¿Por qué publicar la pregunta si sabe que hay una solución de dos caracteres?
Peter Taylor
3
@Howard: Eso coincide con una cadena vacía: jsfiddle.net/RjLxJ
ProgramFOX
10
¿Por qué siempre encuentro estos problemas después de proporcionar una solución inmejorable :(
Cruncher
43
-1: Poner ^y $en posiciones "ilegales" solo hace que sean tratados como personajes ordinarios. Su primer ejemplo coincide con el literal $aen sedy probablemente otros programas.
Ben Jackson
2
@Ben Jackson, eso no es cierto para los POSIX ERE. Trate echo 'a^b' | grep 'a^b'vs echo 'a^b' | grep -E 'a^b'. Echa un vistazo a 9.4.9 ERE Expression
Anchoring
21

5 personajes

/$.^/

/$^/ coincidirá con una cadena vacía, mientras que requerir un carácter intermedio no lo hará.

Brian Glaz
fuente
66
Desafortunadamente, esto coincide "$a^"(o cualquier cosa en lugar de 'a') en Perl ( y tal vez sed ). Sin embargo, sigue siendo agradable.
Josh Caswell
@JoshCaswell: Supongo que Perl podría interpretar $.como la variable actual del número de línea. Que podría estar vacío, en cuyo caso será así /^/.
MvG
Un carácter 'entre' solo significa una cadena de un carácter.
jwg
3
@jwg nota el intercambio ^y$
mniip
Probé el patrón '$^'con grep, pero desafortunadamente coincidía con la cadena '$^'. Smartass grep.
joeytwiddle
19

9 caracteres

No estoy seguro, pero /[^\S\s]/debería ser inigualable ya que no significa ningún personaje, sino al menos uno de ellos.

usuario14325
fuente
No necesitas el +.
Peter Taylor
10
/ [^ \ S \ s] / = 9 caracteres
xem
19

6 personajes

Creo que esta expresión regular que hice funcionará:

/\b\B/

Coincide con un límite de palabra ( \b) que no es un límite de palabra ( \B). Lo que es imposible, ¿realmente tengo que explicarte esto?

El chico con el sombrero
fuente
¿No busca éste un límite de palabra seguido de un límite que no sea de palabra?
grexter89
1
@ grexter89 Sí, pero no pueden tener caracteres intermedios. es decir, el límite y el no límite tienen que ocupar el mismo espacio.
The Guy with The Hat
2
Me gusta este. Buena atrapada.
primo
18

4 personajes

(Solo sabor ECMAScript)

/[]/

En otros sabores, esta no es una clase de caracteres válida ( ]se consideraría un carácter en la clase, por lo que la expresión no es válida, porque la clase nunca está cerrada), pero el estándar ECMAScript acepta clases de caracteres vacías. Dado que es una clase que tiene para que coincida con un personaje (por lo que las cadenas vacías no coinciden), pero ya no se incluye un solo carácter sin carácter real corresponde a ninguno.

Martin Ender
fuente
¿No coincidiría esto con una cadena vacía aunque usted diga que tiene que coincidir con un carácter? ¿O crees que esto es ilegal /[]{0}/? (Ps. Aunque mi propia respuesta se parece parcialmente a la suya, en realidad leí la suya después de escribir la mía.)
nl-x
@ nl-x pega esto en la consola de su navegador: /[]/.test(""). devuelve falso una clase de caracteres nunca puede coincidir con una cadena vacía, incluso si no contiene caracteres (imagino que se implementan como "SI el siguiente carácter en la cadena es uno de los enumerados, coincida; ELSE falla"). /[]{0}/es legal (en ECMAScript) y coincide con la cadena vacía ... sin embargo, no estoy seguro de cómo eso es relevante para mi respuesta.
Martin Ender
Falla en Ruby 2.0
Nakilon
@Nakilon, por supuesto que sí. Ruby no implementa el sabor ECMAScript.
Martin Ender
15

6 caracteres

/b++b/

El cuantificador posesivo busca tantos b como sea posible, luego 1 más. ¿6 caracteres pero puntos de simetría?

VBCPP
fuente
Huh ... acabo de aprender una nueva característica. Aparentemente, mis habilidades de expresión regular están muy desactualizadas. Gracias y +1.
Ilmari Karonen
8

6 personajes

/(\1)/

No es un ganador, pero pensé que era divertido. grep y Python vomitan en este caso, pero Perl parece estar de acuerdo con eso.

Parece ser muy dependiente de la implementación (lo cual no es sorprendente, dada su rareza). Bob informa a continuación que coincide con cualquier cosa en el motor de expresiones regulares de JavaScript.

Josh Caswell
fuente
El motor de expresiones regulares de .NET parece aceptarlo.
Bob
Y siempre coincide (una cadena vacía) sin importar la entrada en JS
Bob
8

Tal vez un poco de trampa, pero ...

\0

... es inigualable en POSIX regex en prácticamente todas, si no todas, las implementaciones. RE BÁSICO y RE EXTENDIDO, incluso.

Y POSIX RE no necesita esas barras y banderas molestas que PCRE tiene.

mirabilos
fuente
+1 ¡Bien! Desafortunadamente, la suela 0no funciona en PERL. "0"=~0es cierto ...
Tomás
único \0ITYM? Sí, la mayoría de las implementaciones de perlre (1) y PCRE no usan cadenas C sino buffers de tamaño limitado, en quienes este truco no funcionará, pero la mayoría de las implementaciones de POSIX RE funcionan en cadenas C.
mirabilos
5

5 caracteres

/^.^/

Coincide con la cadena que comienza con cualquier carácter individual antes de que comience la cadena.

P̲̳x͓L̳
fuente
66
También coincide con la cadena".^"
stand
@boothby: ¿en qué idioma coincide? en Python no. re.findall(r'^.^', '.^', re.DEBUG)
P̲̳x͓L̳
8
+1 para usar el operador de manga (consulte stackoverflow.com/questions/3618340/… )
prototipo del
@boothby ^y .son metacaracteres no literales, que deben escaparse
P̲̳x͓L̳
1
Está roto en Perl. Esta pregunta realmente debería haber establecido algunas reglas básicas sobre el lenguaje.
stand
5

4 char:

/.^/

Funciona con GNU grep 2.5.1 y egrep.

RSFalcon7
fuente
/.^/= 4 caracteres
Alexey Popkov
¿Por qué necesitas el //? esos no son necesarios en todas partes ;-)
RSFalcon7
El /recuento de barras inclinadas cuenta, vea la pregunta original ("incluyendo barras inclinadas y banderas") y la entrada del OP .
Alexey Popkov
¡derecho! Echo de menos leer :(
RSFalcon7
No, por la misma razón que la siguiente: En realidad, "^" solo es especial si se encuentra al comienzo del patrón. Cualquier "^" después de cualquier otra cosa no necesita ser escapado, por lo que esta respuesta es incorrecta.
mirabilos
4

Perl 6 (5 caracteres)

/<!>/

Abuso de reglas de Sorta (porque las expresiones regulares de Perl 6 son diferentes e incompatibles con las expresiones regulares estelares por diseño), pero no me importa. <!>La regla informa a Perl 6 que la expresión regular no coincide.

Konrad Borowski
fuente
4

6 bytes

/(*F)/

Una abreviatura de (*FAIL), compatible con motores regex compatibles con perl. Gracias a @HamZa por señalar esto.

9 bytes

/(*FAIL)/

Debería funcionar con cualquier motor regex que sea compatible con los verbos. No estoy convencido de que esto realmente deba seguir jugando golf.

primo
fuente
1
¿Como funciona esto?
stand
@boothby (*FAIL)es un verbo que siempre falla.
primo
@primo podrías usar /(*F)/:)
HamZa
4

4 caracteres

/$./

Necesita cualquier carácter después de que termine la cadena

c0de Freak
fuente
De manera similar a los otros dos, $solo es especial al final del patrón.
mirabilos
3

4 caracteres con barras 2 sin

En el motor de expresiones regulares del lenguaje TXR, una clase de caracteres vacía []no coincide con ningún carácter y, por lo tanto, sin cadena. Se comporta de esta manera porque la clase de caracteres requiere una coincidencia de caracteres y, cuando está vacía, especifica que ningún carácter puede satisfacerla.

Otra forma es invertir el "conjunto de todas las cadenas que incluyen vacío" expresiones regulares /.*/usando el operador de complemento: /~.*/. El complemento de ese conjunto no contiene cadenas, por lo que no puede coincidir con nada.

Todo esto está documentado en la página del 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".

Las barras no son parte de la sintaxis de expresiones regulares per se; son solo signos de puntuación que delimitan expresiones regulares en la notación de expresión S. Testigo:

# 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
fuente
gracias por tu respuesta y perdón por el recuento de barras. Pensé que sería más fácil incluirlos si la gente usara banderas.
xem
1

6 caracteres

(o 4, dependiendo de cómo lo mires)

/{,0}/
Tercy
fuente
Falla en Ruby 2.0
Nakilon
¿En qué implementaciones de expresiones regulares esto no da un error?
Peter Taylor
Solo lo probé usando preg_match de PHP.
Tercy
1

Esta es una expresión regular de 5 caracteres.

/[]+/

Coincide con un grupo vacío 1 o más veces.

EDITAR:

Eliminó mi respuesta para otros sabores:

/.{-1}/

Cualquier cosa que no sea un número dentro de {} coincidirá con el texto.

Este coincidirá con ". {- 1}"

Ismael Miguel
fuente
Tenga en cuenta que esto solo funciona en el sabor ECMAScript. En la mayoría (¿todos?) Otros, no es una expresión válida.
Martin Ender
¿No es inválido?
Wasi
@Wasi no en sabores conformes con ECMAScript
Martin Ender
0

5 personajes

Espero que esto no suene estúpido: /[]+/

nl-x
fuente
No. No es una expresión regular válida.
The Guy with The Hat
@RyanCarlson Es válido y legal ... Al menos en Ecmascript.
nl-x
-1
/$^/

Una cosa que termina antes de que haya comenzado ...

simon
fuente
77
Coincide con la cadena vacía (en algunas implementaciones RE, de todos modos).
Josh Caswell el
1
Su implementación está rota :)
Simon
2
Mejor avísale a Guido .
Josh Caswell
77
Más importante aún, como Ben Jackson señaló , en Perl, donde no coincide "", que no coincide con una cadena que contiene los dos caracteres literales: "$^".
Josh Caswell
+1 ¡Solo quería publicar lo mismo! @ Josh, funciona en PERL, ¡y no coincide con la cadena vacía! El comentario de Ben está roto, le respondí.
Tomás