You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Vim替换中扩展反向引用处理多段驼峰式字符串?

Vim驼峰命名转大写下划线命名的正确处理方式

问题情况

我有一个三行内容的文件:

HelloStackOverflow
ThisIsMyFirstPost
OnThisWebsite

想要将其转换为:

HELLO_STACK_OVERFLOW
THIS_IS_MY_FIRST_POST
ON_THIS_WEBSITE

尝试使用以下Vim替换命令:

:%s/^\([A-Z][a-z]*\)*\([A-Z][a-z]*\)$/\U\1_\2/g

但由于重复捕获组\([A-Z][a-z]*\)*只会保留最后一次匹配的内容,导致输出结果错误:

STACK_OVERFLOW
FIRST_POST
THIS_WEBSITE

疑问:能否扩展反向引用让第一个捕获组的每次匹配后都添加下划线?

解决办法

不用纠结重复捕获组的反向引用限制,换个思路更高效:

两步替换(直观易调试)

  1. 先在小写字母与后续大写字母之间插入下划线:
:%s/\([a-z]\)\([A-Z]\)/\1_\2/g

执行后文本会变成:

Hello_Stack_Overflow
This_Is_My_First_Post
On_This_Website
  1. 再将所有内容统一转为大写:
:%s/.*/\U&/

即可得到目标格式。

一步到位的组合命令

如果想一次执行完成,可以用管道连接两个命令:

:%s/\([a-z]\)\([A-Z]\)/\1_\2/g | %s/.*/\U&/

原理说明

正则表达式中的重复捕获组(如\(...\)*)在反向引用时,只会返回最后一次匹配的结果,无法通过扩展反向引用来实现“每次匹配后添加下划线”的需求。因此采用“先插入分隔符,再统一转大写”的思路,能避开这个限制,更高效地完成转换。

内容的提问来源于stack exchange,提问作者leonyjiang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 13:01:55