如何替换一次,一个模式的每个输出?
How to replace once, of each output of one pattern?
我想替换一个模式,我不知道确切的词。我需要替换这些词的第一次出现。
输入:-
For example, this is just{an} example to show my{need}. This para{has}
no meaning, just{an} example. Imagine that my{replace} should done in
this para. For example, this is just{an} example to show my{need}.
This para{has} no meaning, just{an} example. Imagine that my{replace}
should done in this para. Some more{text}
要求输出:-
For example, this is Replace_Word example to show Replace_Word. This
Replace_Word no meaning, just{an} example. Imagine that Replace_Word
should done in this para. For example, this is just{an} example to
show my{need}. This para{has} no meaning, just{an} example. Imagine
that my{replace} should done in this para. Some Replace_Word
示例模式 s/\(\w*{\w*}\)/Replace_word/g
我是 vim 的初学者。我知道这是错误的。我认为,需要使用for循环等
0,/Word_to_find/s/Word_to_find/Replace_word/g
获取此函数,然后在您的输入文件缓冲区中执行:
call ReplaceFirst('\S\+{[^}]*}',"REPLACE_WORD")
它应该做你想做的事:
function! ReplaceFirst(pat, rep)
let end = line('$')
let pat_dict = {}
for i in range(1,end)
let line = getline(i)
while 1
let found = matchstr(line, a:pat)
if found == ""
break
endif
let pat_dict[found] = 0
let line = substitute(line, a:pat, '','1')
endwhile
endfor
"do replacement
for k in keys(pat_dict)
execute 'normal! gg'
execute '/\V'.k
execute 's/\V'.k.'/'.a:rep.'/'
endfor
endfunction
在这里测试:
注意这个函数不是那么通用,如果你的模式包含/
,这个函数可能会失败。至少它表明了我的想法。对于这些增强功能,您可以将其完成。
以下方法可以解决问题,但确实可以改进:
function! ReplaceFirst(line1, line2, pattern, replace)
let words = [] " To store all possible patterns
for i in range(a:line1, a:line2) " Loop over lines in the desired range
let line = getline(i)
let c = 1 " Counter for multiple matches in the same line
while 1 " For each match in the same line:
let s = matchstr(line, a:pattern, 0, c)
if s == ""
break
endif
if index(words, s) == -1 " If this match was not already stored:
call add(words, s) " Add this match
endif
let c = c + 1 " Go to next match in the same line
endw
endfor
for word in words " For all found matches:
call cursor(a:line1, 1) " Go to the beginning of range,
call search('\V'.word, 'c') " Then to the first occurence of the match
" Replace the first occurence in the line:
exe 's/\V'.word."/".a:replace
endfor
endf
" Command that takes two args: first one is the pattern, second one is the
" replace word:
command! -range -nargs=* ReplaceFirst call ReplaceFirst(<line1>, <line2>, <f-args>)
" Example:
" :%ReplaceFirst \<\w*{\w*} REPLACE_WORD
我想替换一个模式,我不知道确切的词。我需要替换这些词的第一次出现。
输入:-
For example, this is just{an} example to show my{need}. This para{has} no meaning, just{an} example. Imagine that my{replace} should done in this para. For example, this is just{an} example to show my{need}. This para{has} no meaning, just{an} example. Imagine that my{replace} should done in this para. Some more{text}
要求输出:-
For example, this is Replace_Word example to show Replace_Word. This Replace_Word no meaning, just{an} example. Imagine that Replace_Word should done in this para. For example, this is just{an} example to show my{need}. This para{has} no meaning, just{an} example. Imagine that my{replace} should done in this para. Some Replace_Word
示例模式 s/\(\w*{\w*}\)/Replace_word/g
我是 vim 的初学者。我知道这是错误的。我认为,需要使用for循环等
0,/Word_to_find/s/Word_to_find/Replace_word/g
获取此函数,然后在您的输入文件缓冲区中执行:
call ReplaceFirst('\S\+{[^}]*}',"REPLACE_WORD")
它应该做你想做的事:
function! ReplaceFirst(pat, rep)
let end = line('$')
let pat_dict = {}
for i in range(1,end)
let line = getline(i)
while 1
let found = matchstr(line, a:pat)
if found == ""
break
endif
let pat_dict[found] = 0
let line = substitute(line, a:pat, '','1')
endwhile
endfor
"do replacement
for k in keys(pat_dict)
execute 'normal! gg'
execute '/\V'.k
execute 's/\V'.k.'/'.a:rep.'/'
endfor
endfunction
在这里测试:
注意这个函数不是那么通用,如果你的模式包含/
,这个函数可能会失败。至少它表明了我的想法。对于这些增强功能,您可以将其完成。
以下方法可以解决问题,但确实可以改进:
function! ReplaceFirst(line1, line2, pattern, replace)
let words = [] " To store all possible patterns
for i in range(a:line1, a:line2) " Loop over lines in the desired range
let line = getline(i)
let c = 1 " Counter for multiple matches in the same line
while 1 " For each match in the same line:
let s = matchstr(line, a:pattern, 0, c)
if s == ""
break
endif
if index(words, s) == -1 " If this match was not already stored:
call add(words, s) " Add this match
endif
let c = c + 1 " Go to next match in the same line
endw
endfor
for word in words " For all found matches:
call cursor(a:line1, 1) " Go to the beginning of range,
call search('\V'.word, 'c') " Then to the first occurence of the match
" Replace the first occurence in the line:
exe 's/\V'.word."/".a:replace
endfor
endf
" Command that takes two args: first one is the pattern, second one is the
" replace word:
command! -range -nargs=* ReplaceFirst call ReplaceFirst(<line1>, <line2>, <f-args>)
" Example:
" :%ReplaceFirst \<\w*{\w*} REPLACE_WORD