如何在vim中将C风格的转换转换为C++风格的转换

8

我接手了一些遗留代码,首先我想进行修改。

(int)a + b;

进入
static_cast<int>(a) + b;

有很多这样的任务,手动完成非常耗时。有没有一种方法可以使用vim来实现这一点?

我尝试了类似于

:%s/\(int\).* /static_cast<int>(\2)/g

但是它不起作用,请给予建议。


我会将指针转换为命名的C++转换,以确保正确性,但这些考虑因素不适用于数字类型转换,我会将其保留在原地或可能转换为C++符号int(a)(意思相同)。也就是说,不要引入不必要的新冗长性 - Cheers and hth. - Alf
3
你可能会使用类似于clang-tidy这样的工具,可以获得更好的结果。 - Jason
3个回答

6

试试这个:

:%s/(\(.*\))\([^ ]*\)/static_cast<\1>(\2)/g

根据你的问题,此正则表达式假定变量名后面会有一个空格:

示例:
对于以下测试数据:

(int)a + b
(float)x * y
(int)z+m

结果将会是

static_cast<int>(a) + b
static_cast<float>(x) * y
static_cast<int>(z+m)

解释正则表达式

(\(.*\)) - 匹配括号内的任何内容并捕获它
\([^ ]*\) - 接着匹配任何非空格字符并捕获它


它可能有点过于灵活,因为括号中不是C风格转换的任何内容也将被更改,但它能够正常工作! - user3667089
1
如果我正确理解正则表达式,那么 [^ ](非空格)部分是确定要放入转换中的术语的部分。这本质上是一个无限复杂度的解析问题 - 正则表达式永远无法解决它。(int)(p + q) 被解析为 static_cast<int>((p) + q)。另一方面,很明显如果我们使用了 [^ +-*/%^&|?],那么 z+m 就会被更好地解析。对于 (int) arr[i] 没有快速的解决方案。 - MSalters
1
@user3667089:是的,这个正则表达式相当简单。但是只需将正则表达式更改为:%s/(\(int\|float\|double\))\([^ ]*\)/static_cast<\1>(\2)/g,就可以轻松扩展它以仅匹配一些基本数据类型。但很高兴它在当前形式下对您有所帮助。 - xk0der

0

我在lh-cpp中有几个映射可用于此任务。

在这种情况下,它将是,,sc,,rc,,dc。(这里,,实际上是我的<localleader>)。

它实际上是这样实现的:

function! s:ConvertToCPPCast(cast_type)
  " Extract text to convert
  let save_a = @a
  normal! gv"ay
  " Strip the possible brackets around the expression
  let expr = matchstr(@a, '^(.\{-})\zs.*$')
  let expr = substitute(expr, '^(\(.*\))$', '\1', '')
  "
  " Build the C++-casting from the C casting
  let new_cast = substitute(@a, '(\(.\{-}\)).*',
    \ a:cast_type.'<\1>('.escape(expr, '\&').')', '')
  " Do the replacement
  exe "normal! gvs".new_cast."\<esc>"
  let @a = save_a
endfunction

vnoremap <buffer> <LocalLeader><LocalLeader>dc
    \ <c-\><c-n>:'<,'>call <sid>ConvertToCPPCast('dynamic_cast')<cr>
    nmap <buffer> <LocalLeader><LocalLeader>dc viw<LocalLeader><LocalLeader>dc

...

0
你可以使用这个:
%s/(int)\(a\)/static_cast<int>(\1)/g

这里假设变量名总是a。如果不是,您可以用[a-z]替换a


问题在于你转换表达式,而不是变量。没有正则表达式可以捕获所有表达式并仅限于表达式。 - MSalters

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接