Existe-t-il un équivalent pour les \ zs de vim dans sed ou perl?

11

Dans vim, nous pouvons utiliser l' \zsatome pour dire "vraiment commencer le match ici":

:%s/funnyword\zs.*$/otherword/

Existe-t-il un équivalent pour sed ou même perl?

ninrod
la source

Réponses:

15

En Perl (et PCRE), ceci est réalisable avec un lookbehind de largeur nulle :

(?<=funnyword).*$

qui correspond à "funnyword", mais ne le consomme pas dans le cadre du match. Ceux-ci ne fonctionnent qu'avec du texte de longueur fixe dans l'arrière-plan. Vous pouvez également utiliser des lookbehinds négatifs ( (?<!...)) pour spécifier qu'il n'y a pas de texte.

Dans toute version raisonnablement récente de Perl, \Kest presque un substitut exact de ce\zs que vous utilisez:

funnyword\K.*$

\Ksupprime tout ce qui a été apparié jusqu'à présent mais continue de correspondre à partir de ce point. La partie précédente \Kn'a pas besoin d'être de longueur fixe. C'est également dans PCRE maintenant , mais je ne sais pas dans quelle version il est entré.

\zepeut être obtenu avec un lookahead de largeur nulle à la place, en utilisant (?=...). Ce modèle n'a pas besoin d'être de longueur fixe.


Étant donné que sed utilise des BRE POSIX , il n'y a pas de solution de contournement . Dans ce cas, cependant, vous pouvez le simuler assez facilement à l'aide d'un groupe de capture ordinaire:

sed -e 's/\(funnyword\).*$/\1otherword/'

Vous pouvez faire de même pour l'anticipation positive. Si vous avez vraiment une exigence plus compliquée, vous devrez peut-être vous tourner vers Perl ou une autre approche.

Michael Homer
la source