Fita adesiva Decider Regex

11

Sua tarefa é criar um programa que determine se uma determinada sequência é uma expressão regular válida ou não usando trechos de código provenientes de sites na rede StackExchange.

Para os fins deste desafio, o dialeto expressão regular será um despojado e principalmente mínima conjunto de meta-caracteres: ()*?|\. Como tal, você não poderá usar analisadores de regex internos.

  • \é usado para escapar de meta-caracteres. Deve ser seguido por um meta-caractere.
  • Parênteses sem escape devem ser equilibrados
  • *e ?deve ser precedido por um não caractere meta, um grupo entre parênteses ou um caractere escapado.
  • Todos os outros caracteres ASCII imprimíveis, além de nova linha, tabulação e espaço, devem ser suportados como caracteres não meta. O que acontece com uma sequência contendo outros caracteres é indefinido.
  • O significado real da regex não é importante para esse desafio.

Exemplos

Truthy:
  abc
  a?
  (a|)*
  ()
  a|b*
  \*
  \\
  \\*
  a*b?(cd|e)
  +
  [
  }
  (123\))*
  \|
  (a(b(c|d)*e)*f)*
  (|\)*)
  (abc)+*
  (abc)+
  +abc

^ last test case is an actual newline

Falsy:
  ?abc
  *
  **
  \
  (
  a*?
  a?*
  ?
  a)
  (\)
  (|\)*
  \()
  |*
  (?:abc)
  \\**
  \n

Pontuação

Sua pontuação geral é o número de trechos retirados de perguntas e respostas no StackExchange.

  • Snippets repetidos contam quantas vezes forem usados.
  • Os espaços em branco podem ser adicionados e removidos livremente (por causa de Python, Haskell e outras linguagens sensíveis a espaços em branco) e não contam para a contagem de snippets.
    • A exceção seria se seu código fosse realmente escrito em espaço em branco .
  • Snippets são permitidos em qualquer site StackExchange, desde que sejam provenientes de perguntas, respostas e comentários mais antigos (incluindo o tempo de edição - use revisões mais antigas, se necessário) que esse desafio. (24 de setembro de 2019 às 15:30 UTC)
  • Os snippets podem vir de qualquer lugar no corpo de uma pergunta, resposta ou comentário, esteja ele em um bloco de código pré-formatado ou não.
  • A emenda de um snippet no meio de outra faz com que o snippet externo conte como dois snippets

Menor pontuação ganha!

Beefster
fonte
11
@RobinRyder sim, alterado
Beefster 24/09/19
A postagem pode ser mais antiga ou igual a esse desafio, ou seja, podemos usar trechos do corpo desse desafio?
Jo rei
11
"Como tal, você não poderá usar analisadores de regex internos" Isso significa que ele foi projetado para impedir o uso de um simples ya / nay, ou que somos proibidos de usar regex em nossas respostas?
user0721090601
O @guifa foi projetado para que você não possa simplesmente pegar o mecanismo de regex do seu idioma e ver se ele compila o regex especificado. Todos os idiomas que eu conheço suportam um conjunto maior de meta-caracteres e grupos de captura especializados, para que não correspondam corretamente a esse conjunto de caracteres em todos os casos.
Beefster 25/09/19
11
@ JL2210 Isso daria dois trechos: um para o começo e outro para o fim. Você pode usar um único trecho, desde que ele passa todos os casos de teste e vem de uma resposta / pergunta / resposta que é mais velho do que este desafio
Beefster

Respostas:

6

Perl 6 , 20 trechos

{$_ eq m/[[<-[()*?|\\]>|\\<[()*?|\\]>|'(' <~~>* ')']<[*?]>?|\|]+/}

Experimente online!

Os trechos são retirados de:

{$_ eq, m/[, <-[, ()*?, |\\, ]>, |\\, <[, ()*?, |\\, ]>, |, '(' <~~>* ')', <[, *?, ]>, ?|, \|, ]+/, }.

Essa é principalmente a abordagem gananciosa (tornada óbvia por todos os trechos de um ou dois caracteres). Usei o SymbolHound para procurar os caracteres individuais, e a única otimização real foi o '(' <~~>* ')'snippet, que é retirado da minha própria resposta nas regexes recursivas do Perl 6.

Explicação:

Isso basicamente verifica se a entrada é igual a uma correspondência gananciosa de um regex válido. A razão pela qual não podemos simplesmente usar o próprio regex e adicionar ^$para marcar os fins é porque estamos usando um regex recursivo, que não funcionaria se houvesse ^$marcadores. O regex em si é:

m/[                             ]+/   # Match one or more times
   [              ]  # Any of 
    <-[()*?|\\]> |     # Not a metacharacter
    \\<[()*?|\\]>      # A metacharacter preceded by a \
    '(' <~~>* ')'      # Brackets surrounding a valid regex
                   <[*?]>?  # Optionally followed by a ? or *
                           | \|    # Or just the | metacharacter

Brincadeira
fonte
Até ~~, obrigado!
user0721090601
@guifa Sim, eu aprendi isso através da especificação P6 , que tem muitas coisas que ainda não foram devidamente documentadas. Suspeito ~~que não apareça porque ainda não está totalmente implementado (por exemplo <~~0>), embora existam outras jóias escondidas lá.
Jo rei