Expressão Regular para corresponder (não x) e y (! x e y)

3

Recebi um calendário diário no desktop com quebra-cabeças. Um desses quebra-cabeças decifrava uma citação em que as letras eram substituídas por símbolos. Eu usei alguns RegExs para encontrar palavras mais longas, então usei as palavras retornadas para resolver palavras menores. No quebra-cabeça, os símbolos de fundo branco eram vogais (incluindo 'y') e os símbolos de fundo sombreados eram consoantes.

Vou usar letras aleatórias abaixo, onde em negrito significa consoante, simples significa vogal e em itálico significa que a carta foi dada nas direções.

B O QQ E

O exemplo acima foi decifrado como "feliz" ('e' já foi dado no quebra-cabeça) usando o RegEx

 egrep -i '^[bcdfghjklmnpqrstvwxz][aiouy][bcdfghjklmnpqrstvwxz]{2}[aiouy]$' words

Houve muitos resultados, mas sinto que poderia ter melhorado o RegEx especificando o RegEx logicamente como

  1. Char 1 é uma consoante
  2. Char 2 é uma vogal, mas não 'e' porque foi dado nas direções.
  3. Chars 3 e amp; 4 são a mesma consoante, mas são diferentes de char 1.
  4. Char 5 é uma vogal, mas diferente do char 2.

Outro exemplo seria

O R e W Y D O n

onde usei a instrução grep

egrep -i '^([aiouy])[bcdfghjklmnpqrstvwxz]e[bcdfghjklmnpqrstvwxz][aiouy][bcdfghjklmnpqrstvwxz]n$' words

para definir logicamente a pesquisa como

  1. O caractere 1 é uma vogal e é um grupo capturado porque o mesmo caractere aparece mais tarde na palavra.
  2. Char 2 é uma consoante.
  3. Char 3 é 'e', dado.
  4. Char 4 é uma consoante.
  5. Char 5 é uma vogal.
  6. Char 6 é uma consoante.
  7. Char 7 é a mesma vogal que Char 1.
  8. Char 8 é 'n', dado.
Felizmente, o comando grep retornou uma palavra, "American" (o texto cifrado era uma citação de filme). Eu gostaria de ter sido capaz de especificar no RegEx que Char 4 é uma consoante e não o mesmo que char 2, char 5 é uma vogal e não o mesmo que char 1, etc.

É possível solicitar esse tipo de correspondência de padrões com RegExs? Estou ciente da sintaxe (x|y) para afirmar que um caractere pode ser ' x ' ou ' y ', mas eu não sei da sintaxe, se existe, para especificar (!x) & y

    
por user208145 07.01.2016 / 04:13

1 resposta

3

Você pode usar expressões regulares perl com visões antecipadas negativas.

$ grep -Pi '^([aeiouy])([bcdfghjklmnpqrstvwxz])e(?!)([bcdfghjklmnpqrstvwxz])(?!)([aeiouy])(?!)(?!)([bcdfghjklmnpqrstvwxz])n$' /usr/share/dict/words
American
american
everymen

Expandido:

$ perl -lnE '
    BEGIN { $vowel = qr/[aeiouy]/i; $consonant = qr/[bcdfghjklmnpqrstvwxz]/i }
    say if /^ ($vowel)                  # vowel
              ($consonant)              # consonant
              e                         # literal
              (?!)($consonant)        # different consonant
              (?!)($vowel)            # different vowel
              (?!)(?!)($consonant)  # 3rd different consonant
                                      # first vowel again
              n                         # literal
            $/xi
' /usr/share/dict/words
American
american
everymen

O exemplo do BOQQE seria

grep -Pi '^([bcdfghjklmnpqrstvwxz])([aiouy])(?!)([bcdfghjklmnpqrstvwxz])(?!)([aiouy])$' /usr/share/dict/words

que retorna 779 resultados (444 case sensitive) com meu dicionário.

    
por 07.01.2016 / 20:45