O que significa [[.ch.]] Em uma regex?

11

Título alternativo: O que é uma "sequência de intercalação" ou "elemento de intercalação" em uma regex compatível com POSIX?

Encontrei a definição técnica exata na Seção 9.3.5 das especificações do POSIX , como item 4 da lista, mas não está muito claro para mim.

Pesquisei na web por exemplos e explicações e vim não completamente de mãos vazias, mas definitivamente não iluminadas .

A única coisa que obtive foi que, em certas circunstâncias, você pode fazer seu regex tratar vários caracteres como se fossem um único caractere para fins de comparação de comprimento e determinar qual é a "correspondência mais longa" (já que os regexes são gananciosos e retornar a correspondência mais longa possível).

Isso é tudo? Estou tendo problemas para ver uma utilidade para ele, mas suspeito que meu entendimento esteja incompleto. O que realmente é "agrupar" para uma regex? E como [[.ch.]]o exemplo das especificações do POSIX se relaciona a isso?

Curinga
fonte

Respostas:

7

Os elementos de agrupamento geralmente são referenciados no contexto da classificação.

Em muitos idiomas, a ordenação (como em um dicionário) não é feita apenas por caractere. Por exemplo, em tcheco, chnão classifica entre cge cicomo faria em inglês, mas é considerado um todo para classificação. É um elemento de classificação (não podemos nos referir a um caractere aqui, o caractere é um subconjunto de elementos de classificação) que classifica entre he i.

Agora você pode perguntar: O que isso tem a ver com expressões regulares? , Por que eu gostaria de me referir a um elemento de intercalação em uma expressão entre colchetes? .

Bem, dentro das expressões entre colchetes, usamos ordem. Por exemplo [c-j], em , você deseja que os caracteres entre ce j. Bem e você? Você prefere agrupar elementos lá. [h-i]em uma localidade tcheca corresponde ch:

$ echo cho | LC_ALL=cs_CZ.UTF-8 grep '^[h-i]o'
cho

Portanto, se você conseguir listar um intervalo de elementos de intercalação em uma expressão entre colchetes, esperaria poder listá-los individualmente também. [a-cch]corresponderia aos elementos de intercalação entre ae ce os caracteres ce h. Para ter a-ce o chelemento de agrupamento, precisamos de uma nova sintaxe:

$ echo cho | LC_ALL=cs_CZ.UTF-8 grep '^[a-c[.ch.]]o'
cho

(aqueles em entre ae ce a chum).

Agora, o mundo ainda não é perfeito e provavelmente nunca será. O exemplo acima estava em um sistema GNU e funcionou. Outro exemplo de um elemento de intercalação pode ser ecom um sotaque agudo combinado em UTF-8 ( $'e\u0301'renderizado $'\u00e9'como é).

é e é o mesmo caractere, exceto que um é representado com um caractere e o outro com dois.

$ echo $'e\u301t\ue9' | grep '^[d-f]t'

Funcionará corretamente em alguns sistemas, mas não em outros (não no GNU, por exemplo). E não está claro se $'[[.\ue9.]]'deve corresponder apenas $'\ue9'ou ambos $'\ue9'e $'e\u301'.

Sem mencionar scripts não alfabéticos, ou scripts com diferentes ordens de classificação regionais, coisas como ffi ( ffiem um caractere) que se tornam difíceis de lidar com uma API tão simples.

Stéphane Chazelas
fonte
1

Isso é útil quando caracteres em inglês (não ascii) estão em uso. O exemplo que chvocê menciona é um dígrafo , ou seja, alguns idiomas têm uma letra em seu alfabeto que é / pode ser representada por duas letras em um alfabeto em inglês.

Quando você usa [.ch.]um regexp, basicamente diz: "Espero uma sequência de entrada que não seja em inglês com o dígrafo ch. Quero que meu regexp corresponda ao caractere único ch. Minha linguagem de programação / mecanismo / teclado de regex / teclado não permite que eu escreva este dígrafo para digitar [.ch.]. Não quero dizer a cseguido de um h. Encontre apenas ocorrências do dígrafo como um único caractere. "

[[.ch.]]significa que o dígrafo faz parte de um conjunto de caracteres. Nesse caso, apenas um caractere na verdade. Apenas notação padrão de regexp.

Rolf
fonte
De resposta de Stephane parece que ch é na verdade dois personagens diferentes; é apenas tratado como um para fins de classificação. Tem certeza de que "digraph" é um termo aplicável?
Curinga