正则捕获组能否递归使用?如何用vi正则拆分制表符文件多值字段?
问题解法
正则实现方案(Vim环境)
你写的替换逻辑本身没问题,单次执行仅替换第一个分号的原因是:单次全局替换只会处理当前已存在的每一行一次,替换插入新行后不会自动回溯处理新生成的内容。你可以通过Vim的全局匹配命令让替换自动循环执行,直到所有分号都被替换:
:g/;/ s/^\(.*\t\)\([^;]*\);/\1\2\r\1/g
命令说明:
- 开头的
:g/;/表示全局扫描所有包含分号的行 - 后面跟的替换语句和你之前写的逻辑一致,作用是把每行第一个分号替换为换行+第一列内容
- Vim会自动重复执行该逻辑,直到文件中没有包含分号的行,刚好适配子字段数量不固定的场景,哪怕子字段超过200个也可以正常处理
更高效的大文件处理方案(可选)
如果你的文件体积很大,用awk一行命令处理效率更高,不需要依赖编辑器环境:
BEGIN {FS="\t"; OFS="\t"} {n=split($2, arr, ";"); for(i=1; i<=n; i++) print $1, arr[i]}
直接在终端执行即可生成目标文件:
awk 'BEGIN {FS="\t"; OFS="\t"} {n=split($2, arr, ";"); for(i=1; i<=n; i++) print $1, arr[i]}' 原文件名 > 输出文件名
关于正则递归捕获的说明
标准正则本身不支持这类需要重复复用前序捕获组、动态生成多行的递归操作。你这个需求的本质是对每行的N个分隔符做N次替换,每次替换都需要复用当前行的第一列内容,因此需要借助编辑器/命令行工具的循环执行能力配合正则实现,无法仅靠单条正则表达式完成全量替换。
内容的提问来源于stack exchange,提问作者Kyle Banerjee
相关产品推荐
相关产品推荐

