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.