J'ai répondu à cette question sur SuperUser qui était liée au type d'expressions régulières utilisées lors de la réception d'une sortie.
La réponse que j'ai donnée était la suivante:
tail -f log | grep "some_string.*some_string"
Et puis, en trois commentaires à ma réponse @Bob a écrit ceci:
.*
est gourmand et peut capturer plus que vous ne le souhaitez..*?
est généralement mieux.
Ensuite ceci,
l'
?
est un modificateur sur*
, ce qui rend paresseux au lieu de la valeur par défaut gourmand. En supposant PCRE.
J'ai cherché sur Google PCRE
, mais je n'ai pas pu comprendre quelle est la signification de cela dans ma réponse?
et enfin ça,
Je dois également souligner qu'il s'agit d'expressions régulières (grep exécutant des expressions régulières POSIX par défaut), et non d'un shell global.
Je sais seulement ce qu'est un Regex et son utilisation très basique dans la commande grep. Donc, je n'ai pu obtenir aucun de ces 3 commentaires et j'ai ces questions à l'esprit:
- Quelles sont les différences d'utilisation de
.*?
vs.*
? - Quel est le meilleur et dans quelles circonstances? Veuillez fournir des exemples.
Il serait également utile de comprendre les commentaires, si quelqu'un pouvait
MISE À JOUR: En réponse à la question En quoi Regex diffère-t-il des Shell Globs? @Kusalananda a fourni ce lien dans son commentaire.
REMARQUE: Si nécessaire, veuillez lire ma réponse à cette question avant de répondre pour vous référer au contexte.
la source
.*
vs..*?
La question "différence entre expressions régulières et globes shell" a déjà été abordée sur ce site.Réponses:
Ashok déjà fait remarquer la différence entre
.*
et.*?
, donc je vais juste fournir des informations supplémentaires.grep
(en supposant la version GNU) prend en charge 4 façons de faire correspondre les chaînes:grep
utilise BRE par défaut.BRE et ERE sont documentés dans le chapitre Expressions régulières de POSIX et PCRE est documenté sur son site officiel . Veuillez noter que les fonctionnalités et la syntaxe peuvent varier entre les implémentations.
Il vaut la peine de dire que ni BRE ni ERE ne supportent la paresse :
Donc, si vous souhaitez utiliser cette fonctionnalité, vous devrez utiliser PCRE à la place:
Modifier 1
.*
est utilisé pour faire correspondre le motif "le plus long" 1 possible..*?
est utilisé pour faire correspondre le motif "le plus court" 1 possible.D'après mon expérience, le comportement le plus recherché est généralement le deuxième.
Par exemple, disons que nous avons la chaîne suivante et que nous voulons seulement faire correspondre les balises html 2 , pas le contenu entre elles:
Comparez maintenant
.*
vs.*?
:1. La signification de "plus longue" et "plus courte" dans un contexte d'expression régulière est un peu délicate, comme l'a souligné Kusalananda . Reportez-vous à la documentation officielle pour plus d'informations.
2. Il n'est pas recommandé d'analyser le html avec regex . Ceci est juste un exemple à des fins éducatives, ne l'utilisez pas en production.
la source
.*
vs.*?
?Supposons que je prenne une chaîne comme:
can cats eat plants?
Utiliser le gourmand
c.*s
correspondra à la chaîne entière car il commence parc
et se termine pars
, étant un opérateur gourmand, il continue de correspondre jusqu'à l'occurrence finale de s.Alors que l'utilisation du paresseux
c.*?s
ne correspondra que jusqu'à ce que la première occurrence des
soit trouvée, c'est-à-dire la chaînecan cats
.À partir de l'exemple ci-dessus, vous pourriez être en mesure de recueillir que:
"Gourmand" signifie correspondre à la chaîne la plus longue possible. "Paresseux" signifie correspondre à la chaîne la plus courte possible. Ajout d' un
?
à un quantificateurs comme*
,+
,?
ou{n,m}
rend paresseux.la source
cats
, donc il ne s'agit pas d'appliquer le "plus court possible" strictement dans ce sens.Une chaîne peut être mise en correspondance de plusieurs manières (du plus simple au plus complexe):
En tant que chaîne statique (supposez var = 'Hello World!'):
shell
[ "$var" = "Hello World!" ] && echo yes
grep
echo "$var" | grep -F "Hello"
bash
grep -F "Hello" <<<"$var"
En tant que glob:
shell
echo ./*
# liste tous les fichiers dans pwd. bash
shell
case $var in (*Worl*) echo yes;; (*) echo no;; esac
[[ "$var" == *"Worl"* ]] && echo yes
Il existe des globes de base et étendus. L'
case
exemple utilise des globes de base. L'[[
exemple bash utilise des globs étendus. La première correspondance de fichier peut être basique ou étendue sur un shell comme la configurationextglob
de bash. Les deux sont identiques dans ce cas. Grep n'a pas pu utiliser de globes.L'astérisque dans un glob signifie quelque chose de différent d'un astérisque dans une expression régulière :
glob
* matches any number (including none) of
tous les caractères .regex
* matches any number (including none) of the
élément précédent .En tant qu'expression régulière de base (BRE):
sed
echo "$var" | sed 's/W.*d//'
# print: Bonjour!
grep
grep -o 'W.*d' <<<"$var"
# print Monde!
Il n'y a pas de BRE dans les coques (de base) ou awk.
Expressions régulières étendues (ERE):
bash
[[ "$var" =~ (H.*l) ]]
# match: Bonjour Worl
sed
echo "$var" | sed -E 's/(d|o)//g'
# print: Hell Wrl!
awk
awk '/W.*d/{print $1}' <<<"$var"
# print: Bonjour
grep
grep -oE 'H.*l' <<<"$var"
# print: Bonjour le monde
Expressions régulières compatibles Perl:
grep
grep -oP 'H.*?l
# print: Hel
Uniquement dans un PCRE a
*?
a une signification syntaxique spécifique.Cela rend l'astérisque paresseux (non-cupide): la paresse au lieu de la gourmandise .
Ce n'est que la pointe de l'iceberg, il y a des gourmands, des paresseux , des dociles ou des possessifs . Il y a aussi lookahead et lookbehind mais ceux-ci ne s'appliquent pas à l'astérisque
*
.Il existe une alternative pour obtenir le même effet qu'une expression régulière non gourmande:
L'idée est très simple: n'utilisez pas de point
.
, annulez le caractère suivant à faire correspondre[^o]
. Avec une balise Web:Ce qui précède devrait clarifier complètement tous les commentaires @Bob 3. Paraphraser:
.*
est gourmand.*?
n'est pas.Des questions
Quelles sont les différences d'utilisation de. ? contre. . ?
.*?
n'est valide que dans la syntaxe PCRE..*
est plus portable.[^a]*
Quel est le meilleur et dans quelles circonstances? Veuillez fournir des exemples.
Meilleur? Cela dépend de l'objectif. Il n'y a rien de mieux, chacun est utile à des fins différentes. J'ai fourni plusieurs exemples ci-dessus. En avez-vous besoin de plus?
la source