vi ::如何只替换一行中的第二次出现?

jas*_*cks 5 regex vi options

:s/u/X/2 - 这会将当前和下一行的第一个u替换为X ...

或用X ????替换一行中的第二个字符 IDK.

或者它的其他东西:s?

我怀疑我必须使用某种类型的分组(\ 2?)但我不知道写那个.

我听说sed中的sed和:s选项是相似的,在sed的帮助页面上我发现:

3.1.3. Substitution switches:

Standard versions of sed support 4 main flags or switches which may be added to
the end of an "s///" command. They are:

   N      - Replace the Nth match of the pattern on the LHS, where
            N is an integer between 1 and 512. If N is omitted,
            the default is to replace the first match only.
   g      - Global replace of all matches to the pattern.
   p      - Print the results to stdout, even if -n switch is used.
   w file - Write the pattern space to 'file' if a replacement was
            done. If the file already exists when the script is
            executed, it is overwritten. During script execution,
            w appends to the file for each match.
Run Code Online (Sandbox Code Playgroud)

http://sed.sourceforge.net/sedfaq3.html#s3.1.3

所以::r! sed 's/u/X/2'会工作,虽然我认为有一个特定的vi方式这样做?

IDK如果相关但我使用的是tcsh shell.

还, :version: Version 1.79 (10/23/96) The CSRG, University of California, Berkeley.

lre*_*der 5

这很脆弱,但可能足以做你想做的事。这个带有正则表达式的开关命令:

:%s/first\(.\{-}\)first/first\1second/g

转换这个:

first and first then first again
first and first then first again
first and first then first again
first and first then first again
Run Code Online (Sandbox Code Playgroud)

对此:

first and second then first again
first and second then first again
first and second then first again
first and second then first again
Run Code Online (Sandbox Code Playgroud)

正则表达式查找第一个“first”,后跟使用模式匹配的任何字符,这是(在vim中输入:help non-greedy.\{-}以获取更多信息)的非贪婪版本。这种非贪婪匹配后面是第二个“第一”。 .*

第一个和第二个“first”之间的字符通过用.\{-}括号括起来来捕获,转义结果为,然后在替换中使用(1 表示第一个捕获组)\(.\{-}\)取消引用该捕获组。\1