在我的代码中,我想删除一个以括号开头并以括号结尾的代码块。例如,如果我有这一行
ENDPROGRAM { fprintf(sdfsdfsdfsd....) }
在运行正则表达式后,我希望它最终以
结束ENDPROGRAM
我只想删除括号内的代码和括号本身。我试过这个命令
:%s/\{[a-zA-Z0-0]*\}//g
但它说未找到模式。有什么建议吗? ENDPROGRAM只是一个例子,我喜欢DIV MULT等等
答案 0 :(得分:2)
由于你正在使用Vim,另一种方法是将一个键盘宏记录到一个寄存器中,比如寄存器z。
qz
开始录制。/ENDPROGRAM[enter]
f{
d%
q
。现在使用@z
运行宏,然后使用@@
重复。按住@
键快速重复。
对于不涉及大量文件中数万次更改的一次性作业,这种交互式方法效果很好。您在视觉上确认在每个地方都做了正确的事情。问题是,即使你使用正则表达式完全自动化它,你仍然需要查看每个更改,以确认在提交代码之前完成了正确的事情。
你的正则表达式中的第一个错误是大括号之间的材料必须只是字母和数字。 (我假设0-0是0-9的拼写错误)。请注意,大括号之间还有其他内容,例如空格和圆括号。你想要{.*}
:一个开括号,后跟零个或多个字符,然后是一个右括号。如果碰巧你有变种,比如ENDPROGRAM { abc } { def }
,这个正则表达式也会吃它们。正则表达式从第一个开放式大括号到最后一个大括号匹配。另请注意,如果块包含嵌套的内部括号,则正则表达式{[^}]*}
将不起作用;它停在第一个右大括号,而不是最后一个大括号,因此ENDPROGRAM { { x } }
将转向ENDPROGRAM }
。
第二个错误是您使用%
地址在所有行上运行此操作。您只想在包含ENDPROGRAM
的行上运行它,换句话说:
:g/ENDPROGRAM/s/ {.*}//
“对于包含ENDPROGRAM
匹配项的所有行,找到一个空格,后跟一些括号内的文本,并替换为空。”或者:
:%s/ENDPROGRAM {.*}/ENDPROGRAM/
答案 1 :(得分:2)
当某些事情被打破时,从简单开始并按照您的需要进行操作。一开始不要担心:s
命令;相反,专注于使模式(或正则表达式)正确。
\{
,您将收到错误消息。哎呀,应该只是{
。{[a-zA-Z0-0]*
。 Darn,这是不对的,因为你遗漏了空间。{[a-zA-Z0-0 ]*
。现在我们到了某个地方,但我们也希望匹配括号和点:{[a-zA-Z0-0 ().]*
。0-9
而不是0-0
,而且你完成了:{[a-zA-Z0-9 ().]*}
。此时,您可以利用:s
默认使用当前搜索模式的事实,因此您只需要:%s///
。
答案 2 :(得分:1)
这看起来像是一份工作: (dum da dum duuuuum!)
文字对象!
将光标放在大括号内的任何位置。输入 d a B 。
WOOOOOOOAAAH刚刚发生了什么事?!
aB
在Vim中被称为“文本对象”。在这种情况下,您也可以输入da{
或da}
。文本对象是Vim的运算符可以作用的事物。 d 就是这样一个算子。我相信你认识其他人: c , y 等等。
可视模式也适用于文本对象。而不是daB
,请尝试vaB
。这将选择大括号中的所有文本以及大括号本身。大多数文本对象也有一个“内部”变体,例如 c i B 将删除大括号内的所有内容,并进入插入模式,离开大括号完好无损。
有用于处理HTML / XML标记的文本对象,用于处理引用字符串的对象,用于句子和段落的对象,用于单词和WORDS的对象等。请参阅:help text-objects
的完整列表。