4

我正在使用 vim 编辑器,我想清空类中的所有方法,例如

class A {

     public:
        int getNumber() const {
             return number;
        }

        void setNumber(int num) {
             number = num;
        }


};

我想要一个可以替换的正则表达式,这样结果就是这样

class A {

     public:
        int getNumber() const;

        void setNumber(int num};


};

我知道我可以使用 %s 进行全局替换,但是我正在寻找方法主体下的所有内容。

4

5 回答 5

2

由于大括号当然可以嵌套在您的函数中,不幸的是,不可能创建一个可以匹配相应的结束大括号的正则表达式。

幸运的是,VIM 确实有移动到对应(它将向前移动到下一个大括号/括号/等并跳转到相应的打开/关闭一个),使用 %-key(大多数键盘布局上的 shift-5 I相信吗?),所以基本上,站在左大括号之前的空格上, c%;<ESC> 将用分号替换整个正文。

找到一个函数的左大括号是完全不同的事情,我会看看我是否能为你想出一些东西,但是为了让你继续,执行一次,然后继续点击 . (句点)为每个函数再次执行它。

于 2009-01-25T19:55:04.903 回答
1

我不知道正则表达式可以匹配多行。彼得推荐宏可能是对的。在第一种方法上这样的事情可能会奏效:

[ESC]qa$d%i;0[ESC]q

然后在其他方法的第一行,你可以这样做:

[ESC]@a

下面是它的工作原理:

  • [ESC] - 退出键让你进入正确的模式
  • qa - 将下一个命令保存为名为“a”的宏
  • $ - 跳到行尾
  • d% - 删除到匹配的括号
  • 一世; - 插入分号
  • [ESC] - 退出键让你进入正确的模式
  • q - 停止录制宏

  • @a - 再次调用宏(在下一个方法的行上)

我希望这有帮助。

于 2009-01-25T20:17:10.290 回答
0

我认为这是最好使用录制的宏而不是正则表达式来完成的事情。抱歉,我没有时间为您创建一个案例。要开始,请参阅:

:help q
于 2009-01-25T19:44:25.020 回答
0

正如 roe 所说,对所有可能的输入使用正则表达式是不可能的。您需要为您的语言提供完整的解析器。但是下面的正则表达式解决了可能就足够的问题的一个子集,只要您的文本非常规则并遵守一些约束:

  • 左大括号是与方法标题在同一行的最后一个字符
  • 右大括号的缩进量与开头行相同,位于单独的行中,并且是该行的最后一个字符
  • 行以intor开头void(您可以扩展此列表以包括所有相关类型),忽略前导空格

所以这适用于您的示例输入:

:%s/\v((^\s+)(int|void).{-})\s+\{$\_.{-}^\2\}$/\1;/
  • \v:“非常神奇”模式(避免需要反斜杠转义所有内容)
  • ((^\s+): (开始捕获\1); 捕获该行的缩进级别
  • (int|void):行中的第一个单词(根据需要添加到此列表中)
  • .{-}): 此行上的非贪婪匹配(结束 \1 的捕获)
  • \s+{$: 尽可能多的空格,然后是 a {,然后是行尾
  • \_.{-}:非贪婪匹配所有内容,包括换行符
  • ^\2\}$:从一行的开头,匹配我们上面捕获的空格数,然后是行尾的大括号

如果您知道方法标题行缩进了多少个空格,则可以将其插入正则表达式中,(^\s+)以使其更加安全。

我保证你可以很容易地想到使这个正则表达式失败的可能输入。

于 2009-01-26T02:09:49.080 回答
0

我会使用 ctags 来构建在头文件中声明和定义的函数列表。该列表将包含内联定义的行,而不是查找该行的正则表达式。

然后以相反的顺序转到函数的定义行,搜索它的左括号,然后应用 ad%。只要函数的注释中没有任何不平衡的括号,它就应该可以正常工作。

顺便说一句,为了不丢失定义,我有一个:MOVEIMPL 命令将内联函数定义移动到相关的.cpp。

于 2009-01-26T08:48:18.073 回答