As expressões regulares que contêm quantificadores não-reativos (relutantes) podem ser reescritas para não usá-las?

8

Considere uma linguagem regex com o quantificador ganancioso , o quantificador não-viciado, alternância ordenada e classes de caracteres. (Essa é essencialmente uma sub-linguagem do PCRE, sem referências anteriores, afirmações gerais ou alguns dos outros bits mais sofisticados.) ??

Uma correspondência para um regex em uma sequência é um intervalo semiaberto sobre modo que seja aceito por .R s = s 0s n N s a 0s a 1 - 1 R[uma0 0,uma1)Rs=s0 0snNsuma0 0suma1-1R

Damos uma definição recursiva do que torna uma correspondência melhor que a outra. Uma correspondência para a expressão regular R em uma sequência é melhor que outra correspondência b = [ b 0 , b 1 ) se a 0 < b 0 ou, se a 0 = b 0 e:uma=[uma0 0,uma1)Rb=[b0 0,b1)uma0 0<b0 0uma0 0=b0 0

  • Se é uma classe de personagem: As classes de caracteres têm correspondências únicas, portanto, todas as correspondências na mesma posição para R são iguais. Portanto, este caso é impossível.RR

  • Se :R=ST

    • A parte principal de é uma correspondência melhor para S do que a parte principal de b , ouumaSb
    • As principais partes de e b são igualmente bons resultados para S , e a porção traseira de uma for mais semelhante para T do que o troço traseiro de b .umabSumaTb
  • Se :R=S|T

    • é uma correspondência para S e b não é, ouumaSb
    • e b são iguais para S e a é melhor para S do que b , ouumabSumaSb
    • e b não são resultados para S , mas são jogos para T , e um é uma melhor correspondência para T do que b é.umabSTumaTb

Todas as outras formas sintáticas são reduzidas às três acima para fins de prioridade de correspondência:

  • : R S 0 | S 1 | R=SRS0 0|S1|
  • : R ... | S 1 | S 0R=S?R|S1|S0 0

Esses padrões infinitos são usados ​​apenas para fins de prioridade de correspondência - eles não fazem parte do idioma da correspondência em consideração.

A relação "melhor" é uma ordem linear fraca em todas as correspondências possíveis para um determinado padrão.

Chamada duas expressões regulares match-equivalente se, para toda a cadeia de entrada finito, o conjunto de pares disjuntos melhor correspondência com S é igual ao conjunto de pares disjuntos melhores jogos para T .S,T ST

P: É o caso de cada regex contém o quantificador não-remediado ? existe um regex equivalente de correspondência T que não contém quantificadores não-remediados?S?T

Editar: Esta é uma reescrita completa da pergunta para esclarecer o que estava sendo solicitado.

uckelman
fonte
1
Tentei corrigir o LaTeX na pergunta, mas verifique se é isso que você quis dizer. ( \ttNão impede LaTeX de interpretar caracteres especiais e seqüências de controle!)
Tsuyoshi Ito
2
Você precisa ter cuidado com o que quer dizer com "poder expressivo" de uma expressão regular. Se você considerar apenas o idioma que a expressão regular reconhece, é trivial que os quantificadores relutantes não adicionem mais poder porque eles não alteram o idioma que a expressão regular reconhece em primeiro lugar. Mas acho que você está pensando em propriedades mais refinadas de expressões regulares, como quais substrings são capturados e assim por diante.
Tsuyoshi Ito 21/07
1
Não, L ( a+?) ainda é {a ^ n: n≥1}. Se você executar uma correspondência regex não ancorada (como 'aaaa' =~ /a+?/em Perl), não obterá aaaacomo resultado, mas isso ocorre apenas porque as ramificações são tentadas em uma ordem diferente da a+. Se você fizer isso adequadamente com âncoras (como 'aaaa' =~ /^a+?\z/no Perl), obtém o aaaaresultado.
Tsuyoshi Ito 21/07
1
(1) Fico feliz em ver que meus comentários e respostas foram úteis para você reafirmar melhor a pergunta (mesmo que você não a tenha admitido). (2) Espero que você esteja ciente de que “os conjuntos de correspondências não sobrepostas que S e T têm em t” não estão bem definidos, pois podem haver vários conjuntos de correspondências não sobrepostas. Você está falando sobre a lista que uma correspondência regex global ( //gem Perl) retornaria?
Tsuyoshi Ito 21/07
2
Sua pergunta precisa ser esclarecida; você ainda está falando de "aceitar" uma correspondência quando ganancioso x não ganancioso não muda o que é aceito; é apenas um meio de especificar qual correspondência localizar ao procurar uma correspondência e encontrar muitas.
Eamon Nerbonne

Respostas:

3

Essa resposta é baseada no pressuposto de que a equivalência de dois regexes é definida à medida que eles reconhecem o mesmo idioma. Não responde à pergunta atual.


Você tem um mal-entendido comum de que quantificadores relutantes alteram o conjunto de strings às quais uma expressão regular corresponde. Isso não acontece e apenas altera quais opções são tentadas primeiro.

Por exemplo, se você executar uma correspondência de regex 'aaaa' =~ /a+/no Perl, ela localizará a primeira correspondência na sequência aaaae lembrará qual substring correspondeu a uma variável especial. Mesmo se houver mais de uma substring aaaaque corresponda ao regex especificado, as correspondências diferentes da primeira serão ignoradas.

Se os quantificadores são gananciosos ou relutantes, afeta qual é a primeira correspondência entre muitas correspondências, mas o conjunto de correspondências não muda. Nesse sentido, o conjunto de cadeias correspondentes a uma regex não muda, independentemente de você usar quantificadores gananciosos comuns ou quantificadores relutantes.

Tsuyoshi Ito
fonte
Não, eu estou não falar sobre o conjunto de jogos que um padrão unanchored vai ficar em uma determinada seqüência. Estou falando sobre o conjunto de cadeias para as quais um determinado padrão corresponderá a essas cadeias na sua totalidade. Em outras palavras, estou interessado em reescrever padrões para manter a equivalência sobre o conjunto de strings para o qual a primeira correspondência é a string inteira . a+e a+?não são equivalentes neste sentido: aaaanão é páreo para este último.
uckelman
1
@uckelman: De acordo com sua definição, a string abbbnão está em L ( a*(..)*) porque a primeira correspondência da string abbbcom o regex a*(..)*é abb. Essa não é a definição padrão do idioma reconhecido por uma expressão regular. Se é realmente nisso que você está interessado, você deve dar um nome diferente.
Tsuyoshi Ito 21/07
uckelman, tenho certeza de que a+?combina aaaa. Eu sei que o Regypes Ruby faz.
Raphael
@Raphael: Eu acho que você está falando sobre "aaaa" =~ /a?/retornar true em Ruby, mas isso ocorre porque o padrão corresponde a uma subcadeia de caracteres aaaa , não porque corresponde aaaa.
Tsuyoshi Ito 21/07
Eu perdi um +(editado) e Ruby parece coincidir com a palavra inteira (cf rubular.com).
Raphael