source txt文件:
34|Gurla Mandhata|7694|25243|2788|Nalakankar Himalaya|30°26'19"N
81°17'48"E|Dhaulagiri|1985|6 (4)|China
命令输入:
:%s/\(\d\+\)\(\d\d\d\)/\1,\2/g
命令输出:
34|Gurla Mandhata|7,694|25,243|2,788|Nalakankar Himalaya|30°26'19"N
81°17'48"E|Dhaulagiri|1,985|6 (4)|China
期望的输出:
34|Gurla Mandhata|7,694|25,243|2,788|Nalakankar Himalaya|30°26'19"N
81°17'48"E|Dhaulagiri|1985|6 (4)|China
基本上 1985
应该是1985
而不是1,985
。我尝试将\?
设置为每次模式匹配时停止,然后°+
,因此它必须检测到°
以匹配模式,但没有成功。它只是替换°
之前的所有内容,完全混乱。
我对正则表达式的了解与替补相结合很弱,而且我被困在这里。
编辑
前3个数字代表山脉的高度,3个数字需要用(,)改变,最后一个数字(1985)代表一年,不得改变。 数学解决方案不会成为漏洞,因为有高度低于1900的山脉
答案 0 :(得分:0)
您没有告诉我们1985
和其他数字之间有什么区别,所以我认为您的“小”数字小于2000。
你几乎得到了它:
:%s/(\d*[2-90])(\d\d\d)/\1,\2/g
或者,如果这不是你想要的,你可以使用c
标志(:h s_flags
):
:%s/\(\d\+\)\(\d\d\d\)/\1,\2/gc
答案 1 :(得分:0)
这一行将保留最后3列不变,只是替换它之前的内容:
%s/\v(.*)((\|[^|]*){3}$)/\=substitute(submatch(1),'\v(\d+)(\d{3})','\1,\2','g').submatch(2)/g
请注意,上述行会将1000000
更改为1000,000
而不是1,000,000
。 Vim printf()
不支持%'d
,很可惜。如果你有数字> 1m,我们可以找到其他解决方案。
答案 2 :(得分:0)
我自己解决了这个问题,使用了3个单独的命令;一个用于文件中的每个数字字符串:
%s/^\(\d*|[^|]*|\)\(\d\+\)\(\d\d\d\)|/\1\2,\3|/g
:%s/^\(\d*|[^|]*|\d\+,*\d*|\)\(\d\+\)\(\d\d\d\)|/\1\2,\3|/g
:%s/^\(\d*|[^|]*|\d\+,*\d*|\d\+,*\d*|\)\(\d\+\)\(\d\d\d\)|/\1\2,\3|/g
答案 3 :(得分:0)
如果您想使用perl
:
:%!perl -F'\|' -lane 'for(@F[2..4]) { s/(\d+)(\d{3})/\1,\2/;} print join "|", @F'