首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Vim或sed :替换模式中的字符

Vim或sed :替换模式中的字符
EN

Stack Overflow用户
提问于 2017-07-12 19:22:16
回答 2查看 934关注 0票数 2

我想在所有字符(‘_’)前面加上大写字母的地方用连字符替换下划线,例如QWQW_IOIO、OP_FD_GF_JK、TRT_JKJ等。整个文档都需要替换。

我试图在vim中使用::%s/[A-Z]_[A-Z]/[A-Z]-[A-Z]/g替换它,但这导致了使用QWQ[A-Z]-[A-Z]OIO :(

我尝试使用sed命令:sed -i '/[A-Z]_[A-Z]/ s/_/-/g' ./file_name,这导致了整个行的替换。例如:

QWQW_IOIO variable may contain '_' or '-'线被替换为

QWQW-IOIO variable may contain '-' or '-'

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-07-12 20:48:11

你的第一个vim方法是正确的。但是,您需要使用捕获组来记住在[A-Z]部分中找到了哪个字符。这些都很好地解释了这里:h /\1下的情况。另外,我建议使用\u而不是[A-Z],因为它既短又快。这意味着您想要的解决方案是:

代码语言:javascript
复制
:%s/\(\u\)_\(\u\)/\1-\2/g

或者,如果您想使用魔法设置来提高它的可读性:

代码语言:javascript
复制
:%s/\v(\u)_(\u)/\1-\2/g

另一种选择是限制搜索中被\zs\ze原子替换的部分:

代码语言:javascript
复制
:%s/\u\zs_\ze\u/-/g

这是我所知道的最短的解决方案。

票数 5
EN

Stack Overflow用户

发布于 2017-07-12 20:00:56

假设GNU,这应该能做您想做的事情。

代码语言:javascript
复制
sed -i -r -e 's/([A-Z]+)_([A-Z]+)/\1-\2/g' ./file_name

解释:

-r标志启用扩展正则表达式

[A-Z]+是“一个或多个大写字母”

()将模式组合在一起并创建一个编号的记忆匹配。

\1\2把那些记忆好的火柴放进了替代品。

基本上,这会发现大写字母后面跟着下划线,然后是另一大块大写字母,只将字母块作为两个组来记忆,

代码语言:javascript
复制
([A-Z]+)_([A-Z]+)

然后,它重放这些组,但中间用连字符代替下划线。

代码语言:javascript
复制
\1-\2

最后的g标志要求这样做,即使模式在一行上显示了多次。

请注意,在这种情况下,这一点有点支离破碎:

代码语言:javascript
复制
QWQW_IOIO_ABAB

因为它第一次匹配,而不是第二次;第二部分不匹配,因为第一次匹配使用了IOIO。所以这会导致

代码语言:javascript
复制
QWQW-IOIO_ABAB

此版本删除了+,因此它只匹配一个大写字母,并且不会以相同的方式中断:

代码语言:javascript
复制
sed -i -r -e 's/([A-Z])_([A-Z])/\1-\2/g'

如果有这样的字符串,它仍然有一个小缺陷:

代码语言:javascript
复制
A_B_C

和以前一样,现在只写一个字母而不是多个字母。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45065955

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档