我想这样做:
%s/shop_(*)/shop_\1 wp_\1/
为什么shop_(*)
没有匹配?
答案 0 :(得分:63)
这里有几个问题。
vim regexen中的parens不用于捕获 - 您需要使用\( \)
进行捕获。
*
并不代表您的想法。它表示“之前的0或更多”,因此您的正则表达式意味着“包含shop_
后跟0 + (
的字符串,然后是文字)
。你是重新寻找.
,其中正则表达式为“任何字符”。与明星一起放置.*
表示“0或更多任何字符”。您可能至少需要一个字符,所以请使用.\+
(+
表示“之前的一个或多个”)
使用此:%s/shop_\(.\+\)/shop_\1 wp_\1/
。
可选择在最后一个斜杠之后用g
结束它以替换一行上的所有实例而不是第一行。
答案 1 :(得分:9)
如果我理解正确,您需要%s/shop_\(.*\)/shop_\1 wp_\1/
转义捕获括号并使用.*
匹配任意数量的任何字符。
(您的搜索正在搜索“shop_”,后跟任意数量的左括号,后跟右括号)
答案 2 :(得分:0)
@Luc,如果您在这里查看:regex-info,您会看到vim的行为正确。这是sed的相似之处:
echo "123abc456" | sed 's#^([0-9]*)([abc]*)([456]*)#\3\2\1#'
sed: -e expression #1, char 35: invalid reference \3 on 's' command's RHS
在带有“转义”括号的情况下有效:
echo "123abc456" | sed 's#^\([0-9]*\)\([abc]*\)\([456]*\)#\3\2\1#'
456abc123
我讨厌看到vim损坏-尤其是在行为正确的情况下。
PS我试图将其添加为注释,但无法正确设置格式。
答案 3 :(得分:0)
如果您想避免转义捕获括号并使正则表达式模式语法更接近其他实现(例如 PCRE),请在模式开头添加 \v
(非常神奇!)(参见 { {3}} 了解更多信息):
:%s/\vshop_(*)/shop_\1 wp_\1/