Jak mogę uruchomić: zastąpić tylko część linii, a nie całość?

15

Mam taką linię:

function my_function(argument, another argument, but there are spaces)

Chcę zastąpić znaki spacji (w nazwach argumentów) znakiem podkreślenia. Chciałbym zatem użyć:

:s/\ /_/g

ale jak mogę nie stosować go do całej linii, ale zaczynając od, powiedzmy, pozycji kursora? (Lub trzecie słowo)?

Feffe
źródło
4
W wyrażeniu regularnym, aby opisać bieżącą pozycję kursora, możesz użyć atomu \%#. Tak, można użyć: :s/\v(%#.*)@<= /_/g. Który można opisać jako spację poprzedzoną @<=znakami ( ) po pozycji kursora.
user9433424
1
Ty i Statox zaproponowaliście \%#lewę, zaakceptuję jego odpowiedź, jeśli jej nie napiszecie ... Ale czy któryś z was mógłby wyjaśnić wyrażenie regularne nieco bardziej wyraźnie?
Feffe,

Odpowiedzi:

15

Możesz użyć następującego rozwiązania:

Najpierw użyj, v$aby zaznaczyć tekst od kursora do końca linii. Następnie użyj następującego polecenia:

:s/\%V\ /_/g

\%VWskazują na zmianę tekstu w uprzednio wybranym obszarze wizualnie, zobacz :h /\%V.

Jeśli wezmę twój przykład:

function my_function(argument, another argument, but there are spaces)

Jeśli mój kursor znajduje się w 40. kolumnie i użyję właśnie napisanego polecenia, otrzymuję:

function my_function(argument, another argument,_but_there_are_spaces)

W odpowiedzi na Twój komentarz możesz także użyć

  • \%# który pasuje z pozycji kursora
  • \%>23c który pasuje po 23 kolumnie.
  • \%>'m który pasuje po pozycji znaku

Zobacz :h /\%#, :h /\%>ca :h /\%>'m.

@ User9433424 dał sposób na wykorzystanie \%#w swoim komentarzu. Dla wzoru ze znakiem możesz ustawić go dowcipem, maa następnie użyć:

:s/\%>'a /_/g

Wyjaśnienie wzoru podane przez @ User9433424 jest następujące:

:s/\v(%#.*)@<= /_/
:s/                    substitution command
   \v                  Enable the very magic mode
      %#.*             Any characters from the cursor position
           @<=         Check for matches just before what follows
              space    Followed by a space
               /_/     Substitute the matches by underscores

Będziesz chciał zobaczyć :h \vi:h /\@<=

statox
źródło
To działa dobrze ! Ale tak naprawdę nie jestem przyzwyczajony do selekcji wizualnych, a cały proces wydaje się trochę „ciężki”… Myślisz, że może być coś szybszego?
Feffe,
Tak, pozwól mi zaktualizować swoją odpowiedź :)
statox
User9433424 dał ci tę wskazówkę tuż przed tobą, ale odpowiedziałeś, więc przyjmuję twoją odpowiedź, jeśli to w porządku - czy możesz wyjaśnić wzorzec wyrażenia regularnego, którego używa trochę więcej? Nadal mam z tym problem…
Feffe,
Próbowałem wyjaśnić odpowiedź tak jasno, jak to możliwe, ale jeśli @ User9433424 napisze własną odpowiedź, nie wahaj się jej zaakceptować.
statox
1
Bardzo ładne wyjaśnienie wyrażenia regularnego, dziękuję! I dziękuję za komentarz dotyczący odpowiedzi, której odpowiedź należy zaakceptować :)
Feffe,
5

Możesz użyć funkcji look behind ( :h \@<=), aby upewnić się, że istnieje poprzedzający znak „(” oraz granica końca słowa ( :h \>), aby upewnić się, że podstawienie nastąpi tam, gdzie chcesz.

Tak więc z tekstem:

function my_function(argument, another argument, but there are spaces)

uruchomienie polecenia:

:s/\((.*\)\@<=\> /_/g

będzie produkować:

function my_function(argument, another_argument, but_there_are_spaces)

Może to być łatwiejsze niż konieczność każdorazowego ustawiania kursora, pod warunkiem, że podstawienie ma zawsze znany punkt początkowy.

Antony
źródło
2
Podstawienie nie zawsze ma znany punkt wyjścia: miało to tylko ... poprawić dziwną serię literówek, które zrobiłem. Ale twoja odpowiedź jest jednak interesująca, dzięki!
Feffe,