vim:替换特定字符,但仅在第n次出现后

时间:2016-11-01 19:32:58

标签: regex vim vi text-manipulation

我需要在vim中进行有关正则表达式和文本操作的练习。

所以我有关于历史上得分最多的足球运动员的文件,有50​​个条目看起来像这样:

this.selectCompanyCode = function(companyCode) { dropDownMenus.get(0).click(); var companyCodeOptions = $('[ng-bind-html="' + companyCode + '"]'); return companyCodeOptions.click(); };

字段之间的空格是制表符(\ t)

每个字段都响应不同的类别:等等... 最后一个字段包含玩家玩过的一个或多个俱乐部。(所以不是固定数量的俱乐部)

问题:将所有标签替换为&#39 ;;',除了最后一个字段,其中俱乐部需要由''分隔。

所以我想:我只用逗号替换所有这些,然后用分号替换前7个逗号。但是,你是怎么做的?一切 - 从正则表达式到vim命令 - 都是允许的。

第一部分很简单:1 Cristiano Ronaldo Portugal 88 121 0.73 03 Manchester United Real Madrid 但第二部分,我似乎无法弄明白。

非常感谢任何帮助。

谢谢,芝诺

5 个答案:

答案 0 :(得分:2)

这个答案类似于@Amadan,但它利用了提供表达式作为替换字符串的能力,实际上将第一组选项卡更改为分号的难点:

%s/\v(.{-}\t){7}/\=substitute(submatch('0'), '\t', ';', 'g')/|%s/\t/,/g

分解这是一组三个替代命令。前两个拼凑在一起sub-replace-expression

%s/\v(.{-}\t){7}/\=substitute(submatch('0'), '\t', ';', 'g')/

这样做的目的是找到任何字符后面跟一个标签的七种出现({7}),非贪婪的方式。 ((.{-}\t))。然后我们用替换表达式(submatch(0))的结果替换整个匹配(\=substitute(...))。通过比较,替换表达式很简单,因为它只是将所有选项卡转换为分号。

最后一个替代品只是将该行上的任何其他标签更改为逗号。

请参阅:help sub-replace-expression

答案 1 :(得分:0)

这是你可以做到的一种方式:

:let @q=":s/\t/;\<cr>"
:2,$norm 7@q
:2,$s/\t/,/g

说明:

首先,我们定义一个宏'q',它将用分号替换一个选项卡。现在,在任何一行,我们只需运行此宏 n 次,即可替换第一个 n 标签。要自动对每一行执行此操作,我们使用norm命令:

:2,$norm 7@q

这与在指定范围内的每一行上输入7@q(例如“运行宏'q'七次”)基本相同。从那里,我们可以用逗号替换每个标签。

:2,$s/\t/,/g

答案 2 :(得分:0)

:2,$s/\t\(.*\t\)\@=/;/g
:2,$s/\t/,
  • 将稍后有标签的所有标签更改为;
  • 将所有剩余标签更改为,
编辑:误解了。这是一个固定版本:

:2,$s/\(\(\t.*\)\{7}\)\@<=\t/,/g
:2,$s/\t/;/g
  • 将位于其前面的七个标签的所有标签更改为,
  • 将所有剩余标签更改为;

答案 3 :(得分:0)

我的PatternsOnText plugin(以及其他):SubstituteSelected命令允许指定匹配位置。这样,您可以使用分号轻松替换前8个选项卡,然后使用常规替换将剩余的选项卡更改为逗号:

:2,$SubstituteSelected/\t/;/g 1-8
:2,$s/\t/,/g

答案 4 :(得分:0)

我们通过手动捕获前8个组([^\t]*\t)(...)(...)解决了这个问题,然后用分号(\1;\2;...;)分隔它们,然后用逗号| 2,$s/\t/,/g

替换剩余的标签

感谢大家的帮助!