2009-01-14 4 views
8

ich Text in einemVim regulären Ausdruck alle aber die letzten beiden Ziffern der Nummer

23456789 

Datei folgende haben zu entfernen, wenn ich Befehl den obigen Text verwendet zu ersetzen versucht

1,$s/\(\d\)\(\d\d\d\)\(\d\d\)*\>/\3\g 

Ich erhalte 89 . Sollte es nicht 6789 sein? Kann mir jemand sagen warum es 89 ist.

+12

Hinweis, wenn Sie uns die \ V-Option wechseln, können Sie alle diese Backslashed Parens vermeiden. 1, $ s/\ v (\ d) (\ d \ d \ d) (\ d \ d) *>/\ 3/g ist viel einfacher zu lesen. –

+1

Suchen Sie in etwa so: 1, $ s/\ v^\ d {4} ((\ d {2}) *)/\ 1/ – AmirW

Antwort

1

Gruppe 3 ist als 2-stellig definiert. Wenn Sie die letzten 4 Ziffern, die Sie wollen, \(\d\d\d\d\) ohne * am Ende übereinstimmen. Wenn Sie nur alle Ziffern außer den ersten 4 abgleichen möchten, setzen Sie Ihre * innerhalb der Gruppenübereinstimmung und nicht außerhalb.

+0

sollte nicht * bei der Gruppe 3 das letzte Match 2, 4,6 .. Ziffern? – chappar

+1

Nein, siehe Antwort von rampions – tddmonkey

4

Wie beschrieben, erfasst Ihr Regex eine Ziffer, dann drei Ziffern und dann eine beliebige Anzahl von Gruppen mit jeweils zwei Ziffern. Die dritte Übereinstimmung wird daher immer zweistellig sein, wenn sie existiert. In Ihrem speziellen Testfall ist die '89' in \ 4, nicht \ 3.

Ändern der Regex

1,$s/\(\d\)\(\d\d\d\)\(\d\d\+\)\>/\3\g 

geben Sie ‚6789‘ als das Ergebnis, da es zwei oder mehr Ziffern erfassen wird (bis so viele wie gibt es) in der dritten Gruppe.

+0

(\ d \ d) * entspricht 2 oder mehreren 2er-Zahlen. In unserem Fall sollte es den letzten 4 Ziffern entsprechen. Also, sollte nicht 3 alle 4 Ziffern enthalten. \ 4 wird nichts haben, da ich nur 3() habe. – chappar

+5

(\ d \ d) * passt die Ziffern der Längenvielfache von 2 (also 12, 3456, aber nicht 789), aber nur * fängt das letzte Atom ein, da dieselben Klammern (die gleiche Einfanggruppe) verwendet werden mehrere Paare von Zahlen. Um sicherzustellen, dass du nur mit mehreren Längen übereinstimmst, benutze Hasturkens Regex. – rampion

4

Sie möchten hier eine nicht-einfangende Gruppe verwenden, wie so

1,$s/\(\d\)\(\d\d\d\)\(\%(\d\d\)*\)\>/\3/g 

die hier 6789 als Ergebnis gibt, und wenn wurde Eingang geändert

2345678 

würde die Zeile zu 278

+2

Ich war eigentlich auf der Suche nach der nicht einfangenden Gruppe für Vim Regex. – lambacck

0

Sie möchten wahrscheinlich (benötigen eine zusätzliche Verpackungsgruppe):

%s/\(\d\)\(\d\d\d\)\(\(\d\d\)*\)\>/\3\g 

Obwohl ich nicht sicher bin, warum Sie die ersten 2 Gruppen erfassen.

+0

Warum brauche ich einen zusätzlichen Klammersatz in Gruppe 3? Was war das Problem mit meinem ursprünglichen Beispiel? – chappar

+0

\ (\ d \ d \) * würde in der Tat mit allen Ziffernpaaren übereinstimmen, aber sie werden nicht für spätere Verwendung _capture_. Um es zu erfassen, müssen Sie es in eine eigene Gruppe einhüllen - das ist der zusätzliche Satz von Klammern. – orip

0

Ich habe dieses in nvi versucht und es funktioniert nicht. In Vim funktioniert es, nur dass Sie die endgültige invertierte Strich vor dem g korrigieren müssen, für einen Bindestrich, wie folgt aus:

1,$s/\(\d\)\(\d\d\d\)\(\d\d\)*\>/\3/g

und es wird mit 89. Der Grund ersetzt ist, dass Sie sagen, mit das * dass das letzte \ d \ d null, einmal oder mehrmals wiederholt werden kann, und mit> du sagst Endwortgrenze. Mit der Gruppe 3 Sie sagen, dass Sie die Las Gruppe wollen, aber wegen der * die zwei Ziffern (\ d \ d) sind 89. Herausnehmen der *> Sie können 6789 erhalten. So:

1,$s/\(\d\)\(\d\d\d\)\(\d\d\)/\3/g

Achten Sie auf die> heraus, wer da mit diesem einem schwierigen Teil spielt: 1,$s/\(\d\)\(\d\d\d\)\(\d\d\)\>/\3 Sie bekommen 2389 LOL! Weil vom Ende der Wortgrenzenperspektive dddddd mit 456789 übereinstimmt und es durch die letzten zwei dd ersetzt wird, und das ist 89. So bekommst du 23 + 89 Mind weht!LOL

Verwandte Themen