2016-03-30 17 views
4

In vi, für LinieGibt es einen Standard für den Kontextaustausch?

aaaj

ich den Befehl:

.s/a * \ | j/x/g

Die Linie wendet sich an

xj

statt der erwarteten

xx

Ist das ein Fehler von vi? sed, gaffen und nawk wie erwartet verhalten, zum Beispiel:

% echo aaaj | awk '{gsub(/a*|j/,"x");print}' 
xx 

Auch, wenn anstelle des Befehls oben ich den Befehl

· s/j \ laufen | a */x/g

("j" und "a *" ausgetauscht), dann würde die Zeile wie erwartet "xx" werden.

+0

Regex hat verschiedene Geschmacksrichtungen, siehe vi Dokumentation, um zu erfahren, wie Regex dort implementiert wird. –

+2

"Siehe Dokumentation" ist die Antwort auf fast jede Frage in Stackoverflow. Wenn ich es in einer Dokumentation finden könnte, würde ich natürlich nicht fragen. – user31264

+1

Theoretisch sollte es sowohl "a *" als auch "j" ersetzen, da DFA für "a * \ | j" und "j \ | a *" dasselbe ist. Deine Frage ist gut. Da meine Antwort das ursprüngliche Problem nicht beantwortet, habe ich es entfernt. – doptimusprime

Antwort

3

Das "Problem" ist hier das a* Submuster, das die erste Verzweigung in der Alternation ist kann eine leere Zeichenfolge übereinstimmen.

Wenn der Motor findet aaa, die a* alternative Zweig entspricht den drei a s, und substitute ersetzt alle mit x. Dann versucht der Motor wieder an der Position nach die 3 a s + 1 (siehe die source code comments).

Beachten Sie, dass a* immer übereinstimmt, "gewinnt" und j nie übereinstimmt. Das passiert wegen der Rangfolge, der erste Zweig gewinnt immer in Vim regex. Wenn Sie aaaj jjj ersetzen, wird es zu xjx xjxjxj wechseln, da das Muster jeder Position vor einem nicht übereinstimmenden Zeichen entspricht.

richtige Muster

Wenn es mit einem regulären Ausdruck zu ersetzen, Sie in der Regel wollen nicht alle leeren Stellen zwischen den Zeichen übereinstimmen, die somit nicht dem Muster entsprechen, die logische Lösung ist eine + quantifier zu verwenden , das a\+\|j Muster.

Verwandte Themen