在 Vim 中,如何在子表达式中进行替换?

aza*_*tar 2 regex vim substitution

我想在我的所有 className 前面加上o-而不必手动调整每个 className。我使用 Vim。

我知道替换可以完成这项工作,所以我想出了这个,这显然是行不通的(也是我在这里的原因)。

:%s/class="[^"]*"/\='class="'.substitute(submatch(0), '[^o-]*', 'o-'.submatch(1), 'g').'"'/g
Run Code Online (Sandbox Code Playgroud)

解释:

  1. class="[^"] - 匹配所有实例 class="foo bar baz"
  2. \='class="'.substitute(subexp).'"' - 替换找到的实例 class="subexp"
  3. subexp 在两个应该用原始 className 前缀替换每个空格分隔的类 o-

总而言之,在程序方面,对于 each class="foo bar baz",将每个 className 替换为以 为前缀的 className o-

提前致谢。

(奖金)编辑:怎么可以这样写忽略或与已首先应对的类名o-,遇到时,这样o-o-不是一个导致编辑。

Ken*_*ent 5

例如

class="foo bar baz"
Run Code Online (Sandbox Code Playgroud)

这条线有效:

%s/class="\zs[^"]*\ze"/\=join( map(split(submatch(0)),"'o-'.v:val"), ' ')/
Run Code Online (Sandbox Code Playgroud)

所以有嵌套的函数调用:

  • 我没有使用\<边界,因为万一你的类名中有一些“特殊”字符,它会失败。例如# - or @。我不知道你的语言是不是这样。
  • 子匹配(0)是 "foo bar baz"
  • split() 使它(每个类)进入列表
  • map()添加o-到每个类名
  • join() 将修改后的列表变回字符串

所以在执行这个命令后,你应该看到:

class="o-foo o-bar o-baz"
Run Code Online (Sandbox Code Playgroud)

编辑“奖金”要求:

我们只需要检查每个元素(类名)。检查下面的代码,它应该适合你:

%s/class="\zs[^"]*/\=join(map(split(submatch(0)),"(v:val=~'^o-'?'':'o-').v:val"))/
Run Code Online (Sandbox Code Playgroud)

我们有:

(v:val=~'^o-'?'':'o-').v:val
Run Code Online (Sandbox Code Playgroud)

如果元素以 开头,o-则我们不再添加另一个元素o-