Substitute the n-th occurrence of a word in vim

╄→гoц情女王★ 提交于 2019-12-30 00:37:09

问题


I saw other questions dealing with the finding the n-th occurrence of a word/pattern, but I couldn't find how you would actually substitute the n-th occurrence of a pattern in vim. There's the obvious way of hard coding all the occurrences like

:s/.*\(word\).*\(word\).*\(word\).*/.*\1.*\2.*newWord.*/g 

Is there a better way of doing this?


回答1:


You can do this a little more simply by using multiple searches. The empty pattern in the :s/pattern/repl/ command means replace the most recent search result.

:/word//word//word/ s//newWord/
or
:/word//word/ s/word/newWord/

You could then repeat this multiple times by doing @:, or even 10@: to repeat the command 10 more times.

Alternatively, if I were doing this interactively I would do something like:

3/word
:s//newWord/r

That would find the third occurrence of word starting at the cursor and then perform a substitution.




回答2:


For information,

s/\%(\(pattern\).\{-}\)\{41}\zs\1/2/

also works to replace 42th occurrence. However, I prefer the solution given by John Kugelman which is more simple -- even if it will not limit itself to the current line.




回答3:


Replace each Nth occurrence of PATTERN in a line with REPLACE.

:%s/\(\zsPATTERN.\{-}\)\{N}/REPLACE/



回答4:


This answers your actual question, but not your intent.

You asked about replacing the nth occurrence of a word (but seemed to mean "within a line"). Here's an answer for the question as asked, in case someone finds it like I did =)

For weird tasks (like needing to replace every 12th occurrence of "dog" with "parrot"), I like to use recursive recordings.

First blank the recording in @q

qqq

Now start a new recording in q

qq

Next, manually do the thing you want to do (using the example above, replace the 12th occurrence of "dog" with "parrot"):

/dog
nnnnnnnnnnn

delete "dog" and get into insert

diwi

type parrot

parrot

Now play your currently empty "@q" recording

@q

which does nothing.

Finally, stop recording:

q

Now your recording in @q calls itself at the end. But because it calls the recording by name, it won't be empty anymore. So, call the recording:

@q

It will replay the recording, then at the end, as the last step, replay itself again. It will repeat this until the end of the file.

TLDR;

qq
q
/dog
nnnnnnnnnnndiwiparrot<esc>
@q
q
@q



回答5:


To replace the nth occurrence of PATTERN in a line in vim, in addtion to the above answer I just wanted to explain the pattern matching i.e how it is actually working for easy understanding.

So I will be discussing the \(.\{-}\zsPATTERN\)\{N} solution,

The example I will be using is replacing the second occurrence of more than 1 space in a sentence(string). According to the pattern match code->

  1. According to the zs doc,

    \zs - Scroll the text horizontally to position the cursor at the start (left side) of the screen.

  2. .\{-} 0 or more as few as possible (*)

    Here . is matching any character and {} the number of times. e.g ab{2,3}c here it will match where b comes either 2 or 3 times.

    In this case, we can also use .* which is 0 or many as many possible. According to vim non-greedy docs, "{-}" is the same as "*" but uses the shortest match first algorithm.

  3. \{N} -> Matches n of the preceding atom

    /\<\d\{4}\> search for exactly 4 digits, same as /\<\d\d\d\d>

    **ignore these \<\> they are for exact searching, like search for fred -> \<fred\> will only search fred not alfred.

  4. \( \) combining the whole pattern.

  5. PATTERN here is your pattern you are matching -> \s\{1,} (\s - space and {1,} as explained just above, search for 1 or more space)

"abc subtring def"

    :%s/\(.\{-}\zs\s\{1,}\)\{2}/,/

OUTPUT -> "abc subtring,def"

# explanation: first space would be between abc and substring and second 
# occurence of the pattern would be between substring and def, hence that 
# will be replaced by the "," as specified in replace command above. 



回答6:


Well, if you do /gc then you can count the number of times it asks you for confirmation, and go ahead with the replacement when you get to the nth :D



来源:https://stackoverflow.com/questions/3073865/substitute-the-n-th-occurrence-of-a-word-in-vim

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!