Vim Regex捕获组[bau - > byau:ceu - > cyeu]

Chr*_*ian 118 regex vim regex-group capturing-group

我有一个单词列表:

bau
ceu
diu
fou
gau
Run Code Online (Sandbox Code Playgroud)

我想将该列表转换为:

byau
cyeu
dyiu
fyou
gyau
Run Code Online (Sandbox Code Playgroud)

我没有成功尝试这个命令:

:%s/(\w)(\w\w)/\1y\2/g
Run Code Online (Sandbox Code Playgroud)

鉴于这不起作用,我需要更改什么才能使正则表达式捕获组在Vim中工作?

Joh*_*web 205

解决此问题的一种方法是确保模式由转义括号括起来:

:%s/\(\w\)\(\w\w\)/\1y\2/g
Run Code Online (Sandbox Code Playgroud)

略短(多 -al)是使用\v,这意味着在其后的模式所有的ASCII字符除外'0'-'9','a'-'z','A'-'Z''_'有特殊的含义:

:%s/\v(\w)(\w\w)/\1y\2/g
Run Code Online (Sandbox Code Playgroud)

看到:


Ing*_*kat 40

如果您不想使用反斜杠转义捕获组(这是您错过的),请将\vVim的正则表达式引擎转换为非常神奇的模式:

:%s/\v(\w)(\w\w)/\1y\2/g
Run Code Online (Sandbox Code Playgroud)

  • @JJoao:不,查找/替换框仅用于文字搜索和替换.无论如何,你不应该使用它; 它只是为记事本用户训练轮子. (3认同)

Jua*_*uan 29

您也可以使用更短的模式:

:%s/^./&y
Run Code Online (Sandbox Code Playgroud)
  • %s 将模式应用于整个文件.
  • ^. 匹配该行的第一个字符.
  • &yy在模式之后添加.

  • 令人惊奇的是,经过 10 多年的经验和相当多的 vim 专业知识后,我仍然学习新的技巧,比如使用“&”来添加而不是替换。谢谢 (3认同)
  • @Kiteloopdesign `&` 实际上只是 `\0` 的另一个名称,它是包含匹配的整个序列的捕获组。 (2认同)

Hen*_*ann 13

您还必须转义Grouping paranthesis:

:%s/\(\w\)\(\w\w\)/\1y\2/g
Run Code Online (Sandbox Code Playgroud)

这就是诀窍.

  • 来自 Sublime Text 3,这太可怕了。为什么语法是这样的?转义非文字、普通文本的字符是没有意义的。 (2认同)

Vic*_*art 7

Vim,在选择上,以下

:'<,'>s/^\(\w\+ - \w\+\).*/\1/
Run Code Online (Sandbox Code Playgroud)

或者

:'<,'>s/\v^(\w+ - \w+).*/\1/
Run Code Online (Sandbox Code Playgroud)

解析

Space - Commercial - Boeing

Space - Commercial

相似地,

apple - banana - cake - donuts - eggs

被解析为

apple - banana

解释

  • ^: 匹配行首
  • \-escape (, +,)根据第一个正则表达式(接受的答案)——或在前面加上\v(@ingo-karkat 的答案)
  • \w\+查找一个单词(\w将查找第一个字符):在本例中,我搜索一个单词,然后-搜索另一个单词)
  • .*在捕获组之后需要查找/匹配/排除剩余的文本

附录。 这有点偏离主题,但我建议 Vim 不太适合执行更复杂的正则表达式/捕获。[我正在做类似于以下的事情,这就是我找到这个线程的方式。]

在这些情况下,最好将这些行转储到文本文件并“就地”编辑它

sed -i ...

或者在重定向中

sed ... > out.txt

在终端(或 BASH 脚本,...)中:


echo 'Space Sciences - Private Industry - Boeing' | sed -r 's/^((\w+ ){1,2}- (\w+ ){1,2}).*/\1/'

Space Sciences - Private Industry 

cat in.txt

Space Sciences - Private Industry - Boeing

sed -r 's/^((\w+ ){1,2}- (\w+ ){1,2}).*/\1/' ~/in.txt > ~/out.txt

cat ~/out.txt 

Space Sciences - Private Industry

## Caution: if you forget the > redirect, you'll edit your source.
## Subsequent > redirects also overwrite the output; use >> to append
## subsequent iterations to the output (preserving the previous output).
 
## To edit "in place" (`-i` argument/flag):

sed -i -r 's/^((\w+ ){1,2}- (\w+ ){1,2}).*/\1/' ~/in.txt

cat in.txt

Space Sciences - Private Industry 
Run Code Online (Sandbox Code Playgroud)

sed -r 's/^((\w+ ){1,2}- (\w+ ){1,2}).*/\1/'

(请注意{1,2})允许灵活地查找{x,y}单词的重复 - 请参阅https://www.gnu.org/software/sed/manual/html_node/Regular-Expressions.html

在这里,由于我的短语由 分隔-,因此我可以简单地调整这些参数以获得我想要的内容。