vim - vim - 用逗号分割行并为每个标记添加前缀
问题描述
我有这样的行:
<prefix> <token1>, <token2>, .... <tokenN>;
其中令牌的数量是可变的,每个令牌是一个字符或数字。
我想像这样在 Vim 中拆分它们:
<prefix> <token1>;
<prefix> <token2>;
...
<prefix> <tokenN>;
我尝试抓住这样的模式,/<prefix>\s\+\(\w\+,\s*\)\{1,}\(\w\+\);/
但我不确定如何提取可变数量的令牌(\1 和 \2 仅给定 tokenN-1 和 tokenN)。
想法?提前致谢。
解决方案
如果您的前缀在任何地方都是固定的(您建议使用以 开头的模式/<prefix>\s\+...
),那么您可能可以使用如下简单的东西:
:g/^<prefix>\s/s/,\s\+/;\r<prefix> /g
换句话说,对于以 开头的每一行<prefix>
,用分号、回车和<prefix>
后跟空格的固定替换所有逗号(后面有空格)。
但是假设你<prefix>
的更复杂和多变,并且你想在正则表达式中捕获它:
使用命令解决此问题的一种方法:substitute
是使用对函数的进一步调用substitute()
作为替换的一部分,您可以使用它来替换任意数量的逗号。
一种可能的方法是:
:s/\(\S\+\)\s\+[^,]*\zs\(,\s*[^,]*\)*\ze;$/\=substitute(submatch(0),',\s*',";\r".submatch(1)." ",'g')/
打破模式:
\(\S\+\)
:匹配捕获组中的前缀。(您可以使用更好、更具体的内容,而不仅仅是非空白,以仅正确匹配您关心的行。)\s\+
: 跳过空格。[^,]*
:跳过第一个令牌。\zs
: 标记比赛的开始。替换只会替换这部分。\(,\s*[^,]*\)*
:一个或多个标记的序列,前面有逗号和可选的空格。\ze
: 标记比赛的结束。;$
: 匹配所有末尾的分号。
在这一点上,策略再次是用分号、回车和前缀替换逗号,但要动态地这样做。
这是通过在替换中使用这些来实现的:
\=
:在替换中使用表达式(请参阅:help sub-replace-expression
.)substitute(submatch(0),',\s*',";\r".submatch(1)." ",'g')
:用分号、回车和前缀的序列替换逗号(以及它们后面的可选空格),然后是空格。submatch(0)
:我们正在比赛中执行这样的替换(部分在\zs
和之间\ze
。)";\r"
:替换的开头,分号和回车。.
: 点运算符连接 Vimscript 中的字符串。submatch(1)
: 指回捕获组 1,我们在本例中使用它来捕获前缀。'g'
:替换所有匹配项。
这是一个相当复杂的替换,但具有在单个:s
命令中处理替换的优点,这使得在一个范围内使用它或稍后重复它更容易,而无需记录宏。
在替换中使用该substitute()
函数的技术:s
对于处理捕获组不够用的情况也是一种有用的技术,例如您提供的那个。
推荐阅读
- java - 如何在 Java 中拆分地图项?
- c - 为什么输出的执行顺序不符合预期
- python-3.x - 如何在 Django 中批量创建或更新
- postgresql - SQLAlchemy - postgres 函数的映射结果
- javascript - WebAssembly 新手问题:UnhandledPromiseRejectionWarning: ReferenceError: Cannot access 'obj' before initialization
- kotlin - 在 CircleCI 上运行 Gradle 测试时出现“未找到给定包含的测试”错误
- javascript - 可访问性 Ionic 4 路由焦点位于页面底部
- javascript - 如何在 react-native Flatlist 中管理弹出窗口的动态显示
- javascript - 如何将 webpack 添加到我的 slackbot 项目中?
- r - 在相同数据上获得不同的 cor() 输出?