使用 vim 正则表达式来 prepend/append 个字符或字符串 before/after 个匹配的字符串

using vim regex to prepend/append characters or strings before/after matched strings

假设您有一个这样的列表:

file_exts = [tex~, log~, synctex.gz, aux, synctex, tuc, fls, log, fdb_latexmk, bcf, bbl, blg]

我想用单引号将每个元素括起来。有没有办法像这样在 Vim 中高效地做到这一点?:

file_exts = ['tex~', 'log~', 'synctex.gz', 'aux', 'synctex', 'tuc', 'fls', 'log', 'fdb_latexmk', 'bcf', 'bbl', 'blg']

第二种情况如下。如果我想将一个字符串附加到某些匹配字符串但不替换字符串本身的行的末尾,我该怎么做?这是一个例子

His name is Evan
His phonenumber is 333-444

我想在 /his 匹配的字符串末尾附加一个 ...

His name is Evan...
His phonenumber is 333-444...

我知道我可以通过行号来做到这一点,但在我的用例中这是不可能的。

对于第一个问题。你可以在 [ ... ] 中 select 内容(例如输入 vi[),然后执行以下命令:

:'<,'>s/\%V\([a-z~.]\+\)/''/g

现在我将解释命令的每个部分

  1. '<,'> 是一个范围,这意味着我们只想对 selected 行应用以下命令,而不是整个文件。通常 vim 会在您在可视模式下启动命令时自动插入。
  2. 同样\%V这里的意思是“限制在可视区域内匹配”。 1. 的范围限制匹配仅 selected lines,但不匹配 selected characters.我们需要 \%V 来防止将命令应用于 file_exts 单词。
  3. s/pattern/replacement/只是一个替换命令:它将指定的pattern替换为指定的replacement.
  4. [a-z~.]\+ 只是一个正则表达式,意思是“匹配列表中一个或多个字符的序列:a-z~.".
  5. 我们不想替换,而是修改现有项目。因此,在模式部分,我们将其与 \( ... ) 构造一起保存到(某种程度上)寄存器中,稍后在替换部分将其用作 </code>。所以替换部分只是 <code>''.
  6. 默认情况下 vim 每行仅应用一次替换。我们想多次应用它,所以我们在命令末尾添加了g标志。

这不是最简单的方法,但相当简单明了,而且很容易为类似任务定制。

如果您想了解每个主题的更多详细信息,可以查看 vim 帮助:

:help '<
:help '>
:help \%V
:help pattern
:help :s
:help s/
:help s_flags

第二个问题:除了评论中提到的g/解决方案外,您还可以使用:s

:'<,'>s/\(Evan\|444\)$/...

不使用视觉选择实现第一个的另一种方法是以下正则表达式:

:%s/\([a-z~.]\+\)\([,\]]\)/''/g

它利用了单词末尾总是有一个 ,] 的事实。它确实匹配两组

  1. 您要括起来的词
  2. 单词结束(,]

然后用封闭版本替换第一组,并将第二组添加回末尾。

第一题

这里有一点横向思考:

ci[
<C-r>=split(@", ', ')->map({ idx, val -> "'" . val . "'" })->join(', ')

其中...括号中的内容被拆分,然后引用,然后再次组合。

参见 :help c_ctrl-r:help "=:help split():help map():help lambda:help join()

第二个问题

为此使用 :help :global:help :normal

:g/^His/normal! A...<CR>

哪里……

  • :g/<pattern>/<command> 在匹配 <pattern>
  • 的每一行上执行 <command>
  • :normal <macro> 从当前行开始执行正常模式 <macro>

第一个问题的答案-

:%s/, /', '/g

然后在[之后和]之前手动添加'