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.
- 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!
Respostas:
Perl 6 , 20 trechos
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 é:fonte
~~
, obrigado!~~
que não apareça porque ainda não está totalmente implementado (por exemplo<~~0>
), embora existam outras jóias escondidas lá.