如何在宏中将单词转换为camelCase?


14

我有一个单词列表,像这样:

these are
some
words that I want
to convert to
camel case

我需要一种方法来转动,例如,camel casecamelCase一个宏(或一个办法把每一行视线选择到骆驼情况下)内。

我可以wgUlhx根据需要使用任意多次,但是问题是这不适用于长度不一的单词(因此,例如,它wgUlhxwgUlhx适用于convert this please但不适用于convert these pretty please)。

上述行的期望输出为

theseAre
some
wordsThatIWant
toConvertTo
camelCase

有什么办法可以自动化吗?

Answers:


16

一线

我发现了一个简单的正则表达式替换(假设设置了“魔术”):

:s/ \([a-zA-Z]\)/\u\1/g

这匹配空格后的任何单个字母,保存该字母。然后,对于该行中的每个匹配项,将其替换为已保存的大写字母(\u=大写,\1=首次保存的匹配项)。

通过%:和之间放置一个,在整个文件上套用s

该解决方案的缺点是它是按行排列的(适用于您的示例),但是如果您只想从一行中的多个单词中选择几个单词,则可能会失败。

更全面的解决方案

map <leader>g~ :set opfunc=MyCamelCase<CR>g@
function! MyCamelCase(type, ...)
  let searchsave=@/
    silent s/\%>'\[ \([a-zA-Z]\)\%<']/\u\1/g
  let @/=searchsave
 endfunction

这将创建一个可以对运动进行操作的新操作员。如果具有<leader>as \,则给出以下文本(以|作为光标):

This is some |example text to work with.

打字\g~3w

This is some exampleTextTo work with.

就是说,我们骆驼装箱超过3个字。

替代说明:

s/开始替换。
\%>'\[有点痛苦 该\%>'m说以匹配标记的权利。我们需要mark [,但是在这种模式下也必须转义。因此,这在给操作员的运动之后开始比赛。
\([a-zA-Z\)与上面的单线相同。
\%<']这是另一端,在运动结束之前匹配。
/\u\1/g是上述单线的替代品。


实际上,这不是一个宏,而是一个单一的衬里,但是您可以将其映射到一个键组合。
John O'M。

添加了操作员版本来实现。操作更好。
John O'M。

如果您的答案没有专门使用宏,我认为可以。在我看来,提问者提出了XY问题
tommcdo

@tommcdo是的,你是对的;它不一定是实际的宏。它只是需要某种自动化方法。
2015年

12

另外,我使用vim-abolish插件,该插件提供强制功能:

fooBar变成foo_bar吗?按下crs(强制转到snake_case)。仅有3个击键键,MixedCase(crm),camelCase(crc),snake_case(crs)和UPPER_CASE(cru)都在附近。这些命令支持repeat.vim


2
+1,因为总有一个我不知道的Tim Pope插件。
zool 2015年

5

您可以创建一个递归宏,并通过以下按键针对一行执行此操作:

qqqqqf xgUl@qq

(注意,之间的空间fx是空格键的抽头,而不是暂停)

详细地:

  1. 清除q寄存器。这是必需的,因为我们正在创建一个递归宏。(请参阅步骤5。):qqq

  2. 开始在寄存器q中记录宏: qq

  3. 您不能在w此处使用该动作,因为您希望宏在到达行尾时中止,而不是跳转到下一行。相反,通过按键f和空格键跳到该行的下一个空格字符:f<space>

  4. 删除空格并大写以下字母: xgUl

  5. 递归。由于我们q已在步骤1中清除了寄存器,因此其中没有任何内容,因此将无济于事:@q

  6. 保存宏: q

然后,您可以使用范围将此宏应用于多行:

将宏应用于文件中的每一行:

:%normal @q

将宏应用于第2-5行(包括第2行):

:2,5normal @q

进行视觉选择,然后键入:normal @q。当您按下:键时,这将预填充命令行,从而产生一个将宏应用于所选内容的每一行的命令:

:'<,'>normal @a

无需清除q寄存器,就像qq在开始记录击键之前一样。实际上,这就是为什么qqq要清除q寄存器的原因:)
tommcdo 2015年

当然,如果您要执行某些需要附加q寄存器的操作(即使用qQ),则可能有必要先将其清除。
tommcdo

2
@tommcdo在我的Vim副本中绝对不是这样。(Vim 7.3.87,用调用vim -u NONE)。仅在步骤6中保存寄存器时,才会清除现有内容。因此,如果要递归,则必须在开始之前清除寄存器。
丰富

@tommcdo我已经更新了答案,以使您更清楚为什么需要此步骤。
丰富

我的错,我有点把枪跳到那里了。极好的澄清!
tommcdo

1

请参见http://vim.wikia.com/wiki/Changing_case_with_regular_expressions。 它非常清楚且简洁地说明了\ U,\ L,\ u,\ l修饰符!

其实质如下:

有时候,您可能想要遍历文件并更改与某些任意条件匹配的字符的大小写。如果您很好地理解了正则表达式,则实际上可以很容易地做到这一点。

就像将\ U或\ L放在要更改大小写的反向引用前面,最后是\ E一样简单。Vim将使反向引用的文本分别大写或小写。使用\ u和\ l(末尾没有\ E)仅更改后向引用中第一个字符的大小写。

(“后向引用”是正则表达式的一部分,它引用了正则表达式的前一部分。最常见的后向引用是&,\ 1,\ 2,\ 3,...,\ 9)。

一些示例演示了此技术的强大功能:

小写整个文件

:%s /.*/ \ L&/ g

(&是一个方便的后向引用,它引用匹配的完整文本。)

大写所有以<开头的单词(即打开的HTML标记名称):

:%s/<\(\w*\)/<\U\1/g

另请注意gu和gU命令。

例如,ggguG将小写整个文件。(gg =转到顶部,gu =小写,G =转到EOF)。

通过使用\ 0通用backref而不是名称(\ 1,\ 2等),可以保存正则表达式的replace节上的某些键入内容。

此正则表达式将文件中的一组单词改为大写:

:%s/\(select\)\|\(order)\|\(by\)\|\(from\)\|\(where\)/\U\0/g

不是火箭科学,但是否则您必须这样做:

:%s/\(select\)\|\(order)\|\(by\)\|\(from\)\|\(where\)/\U\1\U\2\U\3\U\4\U\5/g

1
您能否总结一下您在回答中提到的文章?
EvergreenTree

再见?非常重要,如果单链接答案可以,那么几年后,该站点将充满已删除的链接。但是,如果您仅复制所引用链接的重要部分,并且还提供该链接,OP可以从中获取更多信息,那就可以了。
peterh-恢复莫妮卡2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.