2

我有一些这样的文字:

prefix:hello1_Th2ere_a3nd_Ther4e

我想将这些文本更改为:

prefix:Hello1Th2ereA3ndTher4e

我正在尝试运行以下命令:

:1,$s/prefix:\(\([a-z]\)\([a-zA-Z0-9]\+\)_\)\+\([a-z]\)\([a-zA-Z0-9]\+\)/???

那么我不知道如何填写“???”

引用未嵌套时,我们可以通过“\1\2”引用正则表达式引用中的内容,但是当引用嵌套时​​该怎么办。

4

3 回答 3

2

这通常由两个嵌套替换完成:

%s/\v(prefix\:)@<=%([a-zA-Z]%([a-zA-Z0-9]+)_)+[a-zA-Z][a-zA-Z0-9]+/\=substitute(substitute(submatch(0), '\v[^_]+', '\u\0', 'g'), '_', '', 'g')/

请注意,您的正则表达式与示例字符串不匹配:“Th2ere”和“Ther4e”中的“T”不匹配,[a-z]因此我将其替换为[a-zA-Z].

于 2012-10-14T09:26:43.090 回答
1

嵌套匹配仍然计算\1,\2等,从左边开始计算左大括号;那些不适用的内部匹配只是空的。

提示:为避免不必要的捕获组,\%(...\)请用​​于不需要捕获的部分。像 Perl 这样的正则表达式引擎允许命名捕获,这使得这更容易理解,但 Vim 不支持这一点。

于 2012-10-14T15:52:10.743 回答
1

一种完全不同的方法是在split()您的字符串中以“_”字符获取列表。用应用于substitute()列表中的每个字符串map(),然后join()将这些部分组合在一起:

:s/prefix:\zs.*/\=join(map(split(submatch(0), '_'), 'substitute(v:val, ''^[a-z]'', ''\u&'', '''')'), '')

这是相当长的,但它有非常简单的正则表达式。

:help split()
:help substitute()
:help map()
:help join()
:help /\zs
于 2013-12-23T22:44:23.700 回答