我接手了一些遗留代码,首先我想进行修改。
(int)a + b;
进入
static_cast<int>(a) + b;
有很多这样的任务,手动完成非常耗时。有没有一种方法可以使用vim来实现这一点?
我尝试了类似于
:%s/\(int\).* /static_cast<int>(\2)/g
但是它不起作用,请给予建议。
试试这个:
:%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)
解释正则表达式
(\(.*\))
- 匹配括号内的任何内容并捕获它
\([^ ]*\)
- 接着匹配任何非空格字符并捕获它
[^ ]
(非空格)部分是确定要放入转换中的术语的部分。这本质上是一个无限复杂度的解析问题 - 正则表达式永远无法解决它。(int)(p + q)
被解析为 static_cast<int>((p) + q)
。另一方面,很明显如果我们使用了 [^ +-*/%^&|?]
,那么 z+m
就会被更好地解析。对于 (int) arr[i]
没有快速的解决方案。 - MSalters:%s/(\(int\|float\|double\))\([^ ]*\)/static_cast<\1>(\2)/g
,就可以轻松扩展它以仅匹配一些基本数据类型。但很高兴它在当前形式下对您有所帮助。 - xk0der我在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
...
%s/(int)\(a\)/static_cast<int>(\1)/g
这里假设变量名总是a
。如果不是,您可以用[a-z]
替换a
。
int(a)
(意思相同)。也就是说,不要引入不必要的新冗长性。 - Cheers and hth. - Alf