Expressão regular inigualável mais curta


59

Sua missão é escrever a expressão regular válida mais curta que nenhuma string possa corresponder, incluindo a string vazia.

Os envios devem ter este formato ("notação literal"):

/pattern/optional-flags

Regexp mais curto vence. O tamanho da regexp é contado em caracteres. (incluindo barras e bandeiras)

Por favor, explique como o seu regexp funciona (se não for trivial)

Obrigado e divirta-se!


Isso inspirou uma pergunta minha. Vou esperar alguns dias embora. Não quero 2 perguntas regex ativos ao mesmo tempo
— triturador

13
"Válido" de acordo com qual implementação? Acabei de encontrar um um divertido que Perl está tudo bem com (e que é válido de acordo com a única gramática RE posso encontrar , mas que grep e módulo de re de Python recusar.
— Josh Caswell

1
Sim, qual dialeto (s) da regex? Existem muitos diferentes.
— Hippietrail

1
Mas e os nomes dos presidentes? xkcd.com/1313
— Carl Witthoft

@CarlWitthoft Você precisa ser um programa de participar nesse concurso: codegolf.stackexchange.com/q/17718/2180
— Boothby

Respostas:


53

6 caracteres

Seguindo as respostas de primo e Peter Taylor, e uma dica de man perlre:

/(?!)/

Esse regex compatível com perl corresponde a uma sequência vazia que não é seguida por outra sequência vazia.


+1 - Essa é provavelmente a resposta mais curta que é amplamente portátil (junto com /x\by/, mas se eu realmente tivesse que usar uma regex como essa - por qualquer motivo -, essa resposta também será a mais clara)
— Martin Ender

@ m.buettner: Obrigado. O primo /(*FAIL)/é provavelmente mais claro, no entanto. (E, na verdade man perlredada por ele ao mencionar que o meu realmente se expande para o seu internamente.)
— Nate Eldredge

/(*FAIL)/não é tão portátil. E mesmo em Perl, acho que é uma característica mais obscura do que uma aparência negativa.
— Martin Ender

3
Você tem uma visão geral de quase todos os sabores populares (inspirados no Perl) hoje, enquanto eu nunca vi esses verbos de controle em nenhum lugar, exceto no Perl.
— Martin Ender

1
De fato, a documentação do Perl (e -Mre=debug) diz que (?!)é otimizada (*FAIL)pelo otimizador de regex do Perl (de OPFAILacordo com -Mre=debug). Além disso, acho que não vi (*FAIL)fora do Perl 5 (e do Perl 6, onde é chamado <!>).
— Konrad Borowski

39

8 caracteres

/(?=a)b/

Exigimos uma string contendo um caractere que é ambos ae b, o que é obviamente impossível.


19
/(?!x)x/parece ainda mais impossível ;-)
— Howard

@PeterTaylor onde?
— o0 '.

@ Lohoris, onde o que?
— Peter Taylor

@ Peter Taylor, onde ele colocou aquelas regras absurdas de que você fala, eu não consegui encontrá-las.
— o0 '.

7
pessoal, desculpe pela contagem que escolhi, pensei que seria mais simples incluir barras devido às bandeiras opcionais que poderiam vir depois delas.
— xem 14/01

31

5 caracteres

Ao contrário de todos que abusam $e ^... isso realmente funciona no Perl:

/V\A/

\A corresponde ao início da string.


Também funciona com isso ^.
— Tomas


28

8 caracteres

/\w\b\w/

Um limite de palavra ( \b) cercado por caracteres de 'palavra' ( \w- um de [_a-zA-Z0-9]). É incomparável, pois um dos caracteres que precede ou segue um limite de palavra deve ser um caractere que não seja 'palavra'.

A propósito: isso é semelhante à expressão inigualável

/\W\b\W/

onde \Wsignifica caractere não-palavra.


São 8 caracteres de acordo com as regras da competição, porque as barras de empacotamento /contam. Veja a entrada do OP, por exemplo . É uma ótima entrada, no entanto!
— precisa saber é o seguinte

Também pode ser um vencedor (ou empatado com a entrada de Peter Taylor ), dados os problemas dependentes da implementação com algumas das entradas mais curtas!
— precisa saber é o seguinte

Muito elegante! Eu pensei que deveria haver algo assim!
— Tomas

22

4 caracteres

/$a/

procura um "a" após o final da string.

ou

/a^/

pesquisa a antes do início da string.


20
Por que postar a pergunta se você sabe que existe uma solução de dois caracteres?
— Peter Taylor

3
@ Howard: Isso corresponde a uma string vazia: jsfiddle.net/RjLxJ
— ProgramFOX

10
Por que sempre encontro esses problemas depois que uma solução imbatível é fornecida :(
— Triturador

43
-1: Colocar ^e $em posições "ilegais" apenas faz com que sejam tratadas como caracteres comuns. Seu primeiro exemplo coincide com os literais $aem sede provavelmente outros programas.
— Ben Jackson

2
@ Ben Jackson, isso não é verdade para os POSRE EREs. Tente echo 'a^b' | grep 'a^b'vs. echo 'a^b' | grep -E 'a^b'. Confira 9.4.9 ERE Expression
— Anchorage

21

5 caracteres

/$.^/

/$^/ corresponderá a uma cadeia vazia, enquanto exigir um caractere intermediário não corresponderá.


6
Infelizmente, isso corresponde "$a^"(ou qualquer coisa no lugar do 'a') em Perl ( e talvez sed ). Ainda bem legal!
— Josh Caswell

@ JosCaswell: Eu acho que o perl pode interpretar $.como a variável atual do número da linha. O que pode estar vazio; nesse caso, será /^/.
— MvG 14/01

Um caractere 'entre' significa apenas uma cadeia de um caractere.
— GTC

3
@jwg observe o swapped ^e$
— mniip

Eu tentei o padrão '$^'com grep, mas infelizmente ele correspondia à string '$^'. Smartass grep.
— precisa saber é o seguinte

19

9 caracteres

Não tenho certeza, mas /[^\S\s]/deve ser inigualável, pois não significa nenhum personagem, mas pelo menos um deles.


Você não precisa do +.
— Peter Taylor

10
/ [^ \ S \ s] / = 9 caracteres
— xem

19

6 caracteres

Eu acho que esse regex que fiz funcionará:

/\b\B/

Corresponde a um limite de palavras ( \b) que não é um limite de palavras ( \B). O que é imposição - eu realmente tenho que explicar isso para você?


este não procura por um limite de palavras seguido por um não-limite de palavras?
— grexter89

1
@ grexter89 Sim, mas eles não podem ter caracteres no meio. isto é, o limite e o não limite devem ocupar o mesmo espaço.
— O cara com o chapéu

2
Eu gosto deste. Boa pegada.
— primo

18

4 caracteres

(Apenas sabor ECMAScript)

/[]/

Em outros tipos, essa não é uma classe de caracteres válida ( ]seria considerada um caractere na classe, portanto a expressão não é válida, porque a classe nunca é fechada), mas o padrão ECMAScript aceita classes de caracteres vazias. Como é uma classe, ele deve corresponder a um caractere (para que as cadeias vazias não correspondam), mas como nenhum caractere é incluído, nenhum caractere real também será correspondente.


Isso não corresponderia a uma sequência vazia, mesmo que você diga que ela deve corresponder a um caractere? Ou você acha que isso é ilegal: /[]{0}/. (. Ps embora a minha própria resposta parcialmente parece com a sua, eu realmente ler o seu depois de escrever a minha.)
— nl-x

@ nl-x colar isso em consola do seu navegador: /[]/.test(""). retorna falso. uma classe de caractere nunca pode corresponder a uma string vazia, mesmo que não contenha caracteres (imagino que eles sejam implementados como "SE o próximo caractere da string for um dos listados, corresponda; ELSE falhar"). /[]{0}/é legal (no ECMAScript) e corresponde à cadeia vazia ... no entanto, não tenho certeza de como isso é relevante para a minha resposta.
— Martin Ender

Falha no Ruby 2.0
— Nakilon

@Nakilon é claro que sim. Ruby não implementa o sabor ECMAScript.
— Martin Ender

15

6 caracteres

/b++b/

O quantificador possessivo procura o maior número possível de b e, em seguida, mais 1. 6 caracteres, mas aponta para simetria?


Huh ... Acabei de aprender um novo recurso. Aparentemente, minhas habilidades em regex estão desatualizadas. Obrigado e +1.
— Ilmari Karonen

8

6 caracteres

/(\1)/

Não sou um vencedor, mas achei divertido. grep e Python vomitam neste, mas Perl parece bem com isso.

Parece ser muito dependente da implementação (o que não surpreende, dada a sua estranheza). Bob relata abaixo que ele corresponde a qualquer coisa no mecanismo de expressão regular do JavaScript.


O mecanismo de regex do .NET parece aceitá-lo.
— Bob

E sempre corresponde (uma sequência vazia), independentemente da entrada em JS
— Bob

8

Talvez um pouco de trapaça, mas ...

\0

... é inigualável em regex POSIX em praticamente todas, se não todas, implementações. RE BÁSICO e RE estendido, até.

E o POSIX RE não precisa dessas barras e bandeiras traquinas que o PCRE possui.


+1 Bom !! Infelizmente, a sola 0não funciona em PERL. "0"=~0é verdade ...
— Tomas

único \0ITYM? Sim, a maioria das implementações perlre (1) e PCRE não usa cadeias C, mas buffers limitados por tamanho, nos quais esse truque não funcionará, mas a maioria das implementações POSIX RE trabalha com cadeias C.
— mirabilos

5

5 caracteres

/^.^/

Corresponde a sequência que começa com qualquer caractere único antes do início da sequência.


6
Também corresponde a seqüência".^"
— Boothby

@ boothby: em que idioma corresponde? em Python não. re.findall(r'^.^', '.^', re.DEBUG)
— PXL

8
+1 para usar o operador de mangá (consulte stackoverflow.com/questions/3618340/… )
— protótipo

@boothby ^e .são metacaracteres não literais, que precisam ser escapou
— PXL

1
Está quebrado em Perl. Esta questão realmente deveria ter estabelecido algumas regras básicas sobre a linguagem.
— usar o seguinte comando

5

4 caracteres:

/.^/

Funciona com o GNU grep 2.5.1 e egrep.


/.^/= 4 caracteres.
— Alexey Popkov

Por que você precisa do //? aqueles que não são necessários em todos os lugares ;-)
— RSFalcon7

As barras de empacotamento /contam, veja a pergunta original ("incluindo barras e sinalizadores") e a entrada do OP .
— Alexey Popkov

direito! Eu sinto falta de ler :(
— RSFalcon7

Não, pelo mesmo motivo que o abaixo: Na verdade, “^” é especial apenas se estiver no início do padrão. Qualquer "^" depois de qualquer outra coisa não precisa ser escapado, portanto, esta resposta está errada.
— mirabilos

4

Perl 6 (5 caracteres)

/<!>/

Sorta regra abuso (porque as expressões regulares do Perl 6 são diferentes e incompatíveis com as expressões regulares padrão), mas eu não me importo. <!>A regra informa ao Perl 6 que o regex não corresponde.


4

6 bytes

/(*F)/

Abreviação de (*FAIL), suportada por mecanismos de regex compatíveis com perl. Obrigado a @HamZa por apontar isso.

9 bytes

/(*FAIL)/

Deve funcionar com qualquer mecanismo de expressão regular que suporte verbos. Não estou convencido de que isso realmente precise ser jogado de novo.


1
Como é que isso funciona?
— usar o seguinte comando

@boothby (*FAIL)é um verbo que sempre falha.
— primo

@primo que você pode apenas usar /(*F)/:)
— Hamza

4

4 caracteres

/$./

Precisa de qualquer caractere após o término da string


Da mesma forma que os outros dois, $é especial apenas no final do padrão.
— mirabilos

3

4 caracteres com barras 2 sem

No mecanismo de expressão regular da linguagem TXR, uma classe de caracteres vazia [] não corresponde a nenhum caractere e, portanto, a nenhuma string. Ele se comporta dessa maneira porque a classe de caracteres requer uma correspondência de caracteres e, quando está vazia, especifica que nenhum personagem pode satisfazê-la.

Outra maneira é inverter o regex "conjunto de todas as strings, incluindo vazio" /.*/usando o operador complemento:/~.*/ . O complemento desse conjunto não contém seqüências de caracteres e, portanto, não pode corresponder a nada.

Tudo isso está documentado na página do 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".

As barras não fazem parte da sintaxe regex em si; eles são apenas pontuação que delimita expressões regulares na notação de expressão S. Testemunha:

# 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

obrigado pela sua resposta e desculpe novamente pela contagem de barras. Eu pensei que seria mais fácil incluí-los se as pessoas usassem bandeiras.
— xem 15/01

1

6 caracteres

(ou 4, dependendo de como você olha)

/{,0}/

Falha no Ruby 2.0
— Nakilon

Em quais implementações de regex isso não gera um erro?
— Peter Taylor

Eu só testei usando preg_match do PHP.
— Tercy

1

Este é um regex de 5 caracteres.

/[]+/

Corresponde a um grupo vazio 1 ou mais vezes.

EDITAR:

Removida minha resposta para outros sabores:

/.{-1}/

Qualquer coisa que não seja um número dentro de {} corresponderá ao texto.

Este irá corresponder a ". {- 1}"


Observe que isso funciona apenas no sabor ECMAScript. Na maioria (todos?) Outros, não é uma expressão válida.
— Martin Ender

Não é inválido?
— Wasi 14/01

@Wasi não em sabores conformes ECMAScript
— Martin Ender

0

5 caracteres

Espero que isso não pareça estúpido: /[]+/


Não. Regex inválido.
— O cara com o chapéu

@RyanCarlson É válido e legal ... Pelo menos em Ecmascript.
— Nl-x

-1
/$^/

Uma coisa que termina antes de começar ...


7
Corresponde à string vazia (em algumas implementações do RE, de qualquer maneira).
— Josh Caswell

1
Sua implementação é quebrado :)
— simon

2
É melhor que Guido saiba .
— 21413 Josh Caswell

7
Mais importante, como Ben Jackson apontou , em Perl, onde ele não corresponder "", ele não coincidir com uma string contendo esses dois caracteres literais: "$^".
— Josh Caswell

+1 Eu só queria postar o mesmo! @ Josh, ele funciona em PERL, e não corresponde a cadeia vazia! O comentário de Ben está quebrado, eu respondi.
— Tomas
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.