En quoi les expressions régulières diffèrent des caractères génériques utilisés pour filtrer les fichiers


15

Alors que nous utilisons *pour désigner zéro ou plusieurs caractères précédents dans grep, nous utilisons *.cpour trouver tous les fichiers C lorsque nous les utilisons avec la lscommande comme ls *.c. Quelqu'un pourrait-il dire en quoi l'utilisation de *diffère dans ces deux cas?

Réponses:


30

La globalisation des noms de fichiers shell et les expressions régulières utilisent certains des mêmes caractères, et ils ont des objectifs similaires, mais vous avez raison, ils ne sont pas compatibles. La globalisation des noms de fichiers est un système beaucoup moins puissant.

Dans le nom de fichier globbing:

  • * signifie "zéro ou plusieurs caractères"

  • ? signifie "n'importe quel caractère"

Mais dans les expressions rationnelles, vous devez utiliser .*pour signifier «zéro ou plusieurs caractères», et .signifie «tout caractère unique». A ?signifie quelque chose de tout à fait différent dans les expressions rationnelles: zéro ou une instance de l'élément RE précédent.

Crochets ([] ) semblent fonctionner de la même manière dans les deux systèmes sur le système sur lequel je tape ceci, pour les cas simples au moins. Cela inclut des choses comme les classes de caractères POSIX (par exemple [:alpha:]). Cela dit, si vous avez besoin que vos commandes fonctionnent sur de nombreux types de systèmes différents, je vous déconseille d'utiliser quoi que ce soit au-delà de choses élémentaires comme des listes de caractères (par exemple [abeq]) et peut-être des plages de caractères (par exemple [a-c]).

Ces différences signifient que les deux systèmes ne sont directement interchangeables que pour les cas simples. Si vous avez besoin d'une correspondance regex de noms de fichiers, vous devez le faire d'une autre manière. find -regexest une option. (Notez qu'il y a aussi find -name, soit dit en passant, qui utilise la syntaxe glob.)


2
Je ne sais pas si cela s'appelait globbing :)
user3539

3
De plus, il existe différentes saveurs de regex. Tous les regex ne sont pas créés de la même façon! Et vous avez de nombreux autres systèmes de mise en correspondance de modèles, tels que SQL comme , où '%'signifie '*'.
M. Lister

4
POSIX et PCRE (Perl Compatible RE) sont deux versions principales de regexp. Ce dernier est moins long et a plus de fonctionnalités. Les outils et shells Unix utilisent généralement POSIX, la plupart des langages de programmation avec des expressions rationnelles intégrées (à l'exception du shell) utilisent PCRE. Méfiez-vous de la différence lorsque vous lisez du matériel en ligne.
goldilocks

11

Répondre à la question exprimée dans le titre original:

Pourquoi les expressions régulières diffèrent-elles de celles utilisées pour filtrer les fichiers?

L'expansion du nom de fichier est antérieure aux expressions régulières, existait déjà avec la plupart des systèmes d'exploitation (caractères génériques / joker) et est beaucoup plus simple et intuitive que cette dernière.

Bien qu'il *.txtsoit facilement compréhensible par les utilisateurs occasionnels, l'analogue .*\.txtest quelque chose de plus ciblé pour les utilisateurs / programmeurs expérimentés, sans oublier ^.*\.txt$...


2
Une autre raison de la partie «pourquoi»: la vitesse. Les expressions régulières sont plus lentes: pastebin.com/3iNCgkE3
manatwork

3
*.txtn'est pas égal .*\.txt, il est (la plupart du temps) égal .*\.txt$car il ne peut rien y avoir après .txt(en supposant au moins un remplacement de nom de fichier raisonnable ). Peut-être même ^.*\.txt$quelque peu en fonction de l'utilisation. Prouve votre point?
un CVn le
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.