Dans mon répertoire personnel, j'ai un dossier drupal-6.14 qui contient la plateforme Drupal.
À partir de ce répertoire, j'utilise la commande suivante :
find drupal-6.14 -type f -iname '*' | grep -P 'drupal-6.14/(?!sites(?!/all|/default)).*' | xargs tar -czf drupal-6.14.tar.gz
Cette commande gzipe le dossier drupal-6.14, en excluant tous les sous-dossiers de drupal-6.14/sites/ sauf sites/all et sites/default, qu'elle inclut.
Ma question porte sur l'expression régulière :
grep -P 'drupal-6.14/(?!sites(?!/all|/default)).*'
L'expression fonctionne pour exclure tous les dossiers que je souhaite exclure, mais je n'ai pas tout à fait compris pourquoi.
C'est une tâche courante d'utiliser des expressions régulières pour
Faire correspondre toutes les chaînes, à l'exception de celles qui ne contiennent pas le sous-modèle x. Ou en d'autres termes, nier un sous-modèle.
Je (pense) comprendre que la stratégie générale pour résoudre ces problèmes est l'utilisation de lookaheads négatifs, mais je n'ai jamais bien compris à quel niveau les look(ahead/behind)s positifs et négatifs fonctionnent.
Au fil des ans, j'ai lu de nombreux sites Web à leur sujet. Les manuels de regex PHP et Python, d'autres pages comme http://www.regular-expressions.info/lookaround.html et ainsi de suite, mais je n'ai jamais vraiment eu une compréhension solide d'eux.
Quelqu'un pourrait-il expliquer comment cela fonctionne, et peut-être fournir quelques exemples similaires qui feraient des choses similaires ?
-- Mise à jour Un :
En ce qui concerne la réponse d'Andomar : peut-on exprimer plus succinctement un double negative lookahead comme une seule instruction positive lookahead :
c'est-à-dire :
'drupal-6.14/(?!sites(?!/all|/default)).*'
équivalent à :
'drupal-6.14/(?=sites(?:/all|/default)).*'
???
-- Mise à jour Deux :
Comme l'ont souligné @andomar et @alan moore - on ne peut pas remplacer un double negative lookahead par un positive lookahead.