Qual é a definição de uma expressão regular?

10

Recentemente, entrei em uma discussão amigável com Ghoti sobre o que constitui uma expressão regular nos comentários da minha resposta a esta pergunta. Afirmei que o seguinte é uma expressão regular:

`[Rr]eading[Tt]est[Dd]ata`

Ghoti discordou, alegando que é um arquivo global. A página da glob na wikipedia afirma que (ênfase minha):

Os globos não incluem sintaxe para a estrela Kleene, que permite várias repetições da parte anterior da expressão; portanto, elas não são consideradas expressões regulares, que podem descrever um conjunto maior de idiomas regulares sobre qualquer alfabeto finito.

No entanto, não há citação para essa alegação, indicando que é apenas a opinião de um editor da wikipedia específico.

A especificação The Single UNIX ®, versão 2 , afirma que uma expressão regular básica (BRE) pode até ser um único caractere:

Um caractere comum é um BRE que corresponde a si mesmo: qualquer caractere no conjunto de caracteres suportado, exceto os caracteres especiais BRE listados em Caracteres Especiais BRE.

Então, qual é a definição de uma expressão regular no mundo * nix, e essa definição exclui as falhas de arquivo?

terdon
fonte
6
No CS teórico, uma expressão regular é uma descrição de uma linguagem regular, que pode ser reconhecida por um autômato finito. No mundo Unix, é muito mais complicado, e não há uma definição única. Existem 2 dialetos regex no POSIX especificação: Extensão e básicos, que são utilizados por ferramentas como grep, sed, e awk. O Vim usa sua própria variedade, assim como o Perl.
Jw013
Então, por essa definição, um arquivo glob é um BRE, certo?
terdon
2
Não, um arquivo glob NÃO é um BRE - o que faz você pensar que é? Se você ler a descrição POSIX de BRE e a descrição POSIX de globbing, notará que elas não são as mesmas. Por exemplo, *tem dois significados diferentes em BRE e globs. Nota: Eu não acho que o termo glob seja usado em qualquer lugar da especificação POSIX - ele se chama Pattern Matching e é descrito no capítulo da linguagem shell.
jw013

Respostas:

10

Como lk- disse, a -nameopção de findtratará o argumento como uma glob, não como uma expressão regular.

Se uma string é interpretada como glob ou regex ou apenas uma string simples depende do que está sendo usado para interpretar. É uma questão de contexto. A cadeia de caracteres no seu exemplo, [Rr]eading[Tt]est[Dd]atapode ser avaliada em um número de maneiras diferentes, mas o que é depende de como você está usando. Use-o como um globo, é um globo. Use-o como uma regex, é uma regex. No caso da pergunta em que isso se originou , o OP descreveu a sequência como um regex. Portanto, podemos assumir que ele estava planejando interpretá-lo como um regex.

Um único caractere também pode ser uma expressão regular, absolutamente. Também pode ser uma string e também pode ser uma glob. Pode ser interpretado como um byte ou um tinyint, se você preferir. Tudo depende do contexto.

Há várias especificações para expressões regulares de várias formas. BRE e ERE estão bem documentados. PCRE adiciona dezenas de funcionalidades. Muitos intérpretes de regex implementarão, por exemplo, "todo o ERE e alguns do PCRE". Ou eles fazem o ERE menos algum recurso. Se você seguir especificações formais, muitas ferramentas reivindicam suporte a regex que acaba incorreto ou incompleto. Conhecer os detalhes permite adaptar suas soluções à coleção de funcionalidades disponíveis em qualquer ferramenta que esteja avaliando seu regex.

Então ... se você está procurando definições que "excluem" globs, está vendo isso da perspectiva errada. O que é determinado é como você o usa .

ghoti
fonte
7

[Rr]eading[Tt]est[Dd]ataparece ser válido tanto como expressão glob como regular, e acredito que tenha o mesmo "significado" em ambas as interpretações. No entanto, a -nameopção de findtratará o argumento como uma glob, não como uma expressão regular.

Essa distinção será importante se você fornecer um argumento como foo*, que é um glob válido e uma expressão regular válida, mas tem um significado diferente, dependendo da interpretação:

Se interpretado como um padrão glob, isso vai corresponder foo, foobar, foo123, etc.

Se interpretado como uma expressão regular, isso vai corresponder fo, foo, foooooo, etc.

lk-
fonte
Obrigado, vejo a diferença entre um padrão glob e uma regex. Qual é a definição formal de uma regex?
terdon
1
Não sei se existe uma única definição para "expressões regulares", pois o termo é comumente usado. Existem especificações de sintaxe diferentes, como expressões regulares POSIX ou expressões regulares Perl, que incluem outros "recursos", como referências anteriores ou lookaheads. Elas podem não ser mais expressões regulares no sentido mais estrito (no contexto de linguagens formais regulares), mas ainda são referidas como tais.
lk-