Regex Vim正则表达式:覆盖回引用?
项目: 以维基百科的罗马执政官名单为例,将数据放在CSV中,这样我就可以绘制一张图表,显示不同氏族在执政方面的兴衰 示例数据源:Regex Vim正则表达式:覆盖回引用?,regex,parsing,vim,csv,backreference,Regex,Parsing,Vim,Csv,Backreference,项目: 以维基百科的罗马执政官名单为例,将数据放在CSV中,这样我就可以绘制一张图表,显示不同氏族在执政方面的兴衰 示例数据源: 509,L. Iunius Brutus,L. Tarquinius Collatinus suff.,Sp. Lucretius Tricipitinus,P. Valerius Poplicola suff.,M. Horatius Pulvillus, 508,P. Valerius Poplicola II,T. Lucretius Tricipitinus
509,L. Iunius Brutus,L. Tarquinius Collatinus
suff.,Sp. Lucretius Tricipitinus,P. Valerius Poplicola
suff.,M. Horatius Pulvillus,
508,P. Valerius Poplicola II,T. Lucretius Tricipitinus
507,P. Valerius Poplicola III,M. Horatius Pulvillus II
Vim搜索:
/\v(\d+|suff\.),((\w+\.=) (\w+)(\s\w+)=(\s\w+)=(\s[iv]+)=(\s\(.{-}\))=,=){,2}
因此,本质上:
(\d+| suff\)
(外部组){,2}
(\w+。=)
(\w+)
(\s\w+)=
(\s\w+)=
(\s[iv]+)=
(\s\({-}\)=
\1: year or suffect
\2: the entire second outer group
\3: Praenomen of second outer group (same with all below)
\4: Nomen
\5: Cognomen
\6: Agnomen
\7: Iteration
\8: Explanatory note
问题是我不知道如何捕获第一个外部群体。这就像\2和\3-\8引用在看到第二个外部组时被覆盖一样
使用此替换:
:%s//1:{\1}^I2:{\2}^I3:{\3}^I4:{\4}^I5:{\5}^I6:{\6}^I7:{\7}^I8:{\8}^I9:{\9}
我得到这个输出:
1:{509} 2:{L. Tarquinius Collatinus} 3:{L.} 4:{Tarquinius} 5:{ Collatinus} 6:{} 7:{} 8:{} 9:{}
1:{suff.} 2:{P. Valerius Poplicola} 3:{P.} 4:{Valerius} 5:{ Poplicola} 6:{} 7:{} 8:{} 9:{}
1:{suff.} 2:{M. Horatius Pulvillus,} 3:{M.} 4:{Horatius} 5:{ Pulvillus} 6:{} 7:{} 8:{} 9:{}
1:{508} 2:{T. Lucretius Tricipitinus} 3:{T.} 4:{Lucretius} 5:{ Tricipitinus} 6:{ II} 7:{} 8:{} 9:{}
1:{507} 2:{M. Horatius Pulvillus II} 3:{M.} 4:{Horatius} 5:{ Pulvillus} 6:{ II} 7:{} 8:{} 9:{}
我无法访问第一个外部组中的那些组。我认为它们被覆盖了:它们被覆盖了吗?如果是这样的话,有办法解决吗
编辑:
原名
Vim regex(或任何兼容的regex):如果外部组被迭代,如何引用组(组内)?是的,在重复中捕获组会被覆盖到最新的匹配值。根据链接页面底部附近的部分: 正则表达式引擎不会永久替换正则表达式中的反向引用。每次需要使用时,它都将使用保存到反向引用中的最后一个匹配项。如果通过捕获括号找到新的匹配项,则会覆盖以前保存的匹配项 您必须明确写出一定数量的捕获组 我并不特别熟悉vim的正则表达式引擎,因此这里有一个简单的示例。
假设您的文本是abc 12 345 6789 xyz
# with repetition
/^\w+( \d+){1,3} \w+$/
# yields:
# 0: abc 12 345 6789 xyz
# 1: 6789
# -----
# writing out each subpattern
/^\w+( \d+)( \d+)?( \d+)? \w+$/
# yields:
# 0: abc 12 345 6789 xyz
# 1: 12
# 2: 345
# 3: 6789
请注意,由于重复范围为
{1,3}
,我将第二个和第三个(\d+
)设置为可选的?
,我将其分解为子步骤,使用vim函数,而不是使用所有正常的(双关语)方式:
看到我做了什么吗?让事情变得简单明了
Edit稍微减少懒惰,让我们定义一个helper函数,将其拆分为至少3个子字符串,并将它们分开:
function! Consul(s)
return join((split(a:s) + ["","",""])[0:2], "\t")
endf
现在将替换减少为(仅限SO的换行符)
在你的输入上运行这种美会产生
509 L. Iunius Brutus L. Tarquinius Collatinus
suff. Sp. Lucretius Tricipitinus P. Valerius Poplicola
suff. M. Horatius Pulvillus
508 P. Valerius Poplicola T. Lucretius Tricipitinus
507 P. Valerius Poplicola M. Horatius Pulvillus
我敢肯定,这将是一个非常简单的步骤,进一步装饰现在整齐的标签分隔栏,以您的喜好。我可以补充一下,但现在,我能想到的最简单的事情是:
:%s/\v(.{-})\t(.{-})\t(.{-})\t(.{-})\t(.{-})\t(.{-})\t(.{-})$/1:{\1}\t2:{\2}\t3:{\3}\t4:{\4}\t5:{\5}\t6:{\6}\t7:{\7}/g
结果:
1:{509} 2:{L.} 3:{Iunius} 4:{Brutus} 5:{L.} 6:{Tarquinius} 7:{Collatinus}
1:{suff.} 2:{Sp.} 3:{Lucretius} 4:{Tricipitinus} 5:{P.} 6:{Valerius} 7:{Poplicola}
1:{suff.} 2:{M.} 3:{Horatius} 4:{Pulvillus} 5:{} 6:{} 7:{}
1:{508} 2:{P.} 3:{Valerius} 4:{Poplicola} 5:{T.} 6:{Lucretius} 7:{Tricipitinus}
1:{507} 2:{P.} 3:{Valerius} 4:{Poplicola} 5:{M.} 6:{Horatius} 7:{Pulvillus}
缺少链接:消除了一个bug并添加了一个步骤来完成解决方案哇,我从未见过这些join和submatch命令。如果有机会,我会尝试一下。split
命令在concur函数中做什么?我只知道split命令会打开一个新窗口;如何将其与join命令结合起来?这是函数,而不是函数。另请参见,嗯。我想迭代外部组的一个原因是因为Vim告诉我“太多了”。“否则我可能会做得太懒,然后把整个组写两遍。”I+1这是解释的答案
:%s/\v(.{-})\t(.{-})\t(.{-})\t(.{-})\t(.{-})\t(.{-})\t(.{-})$/1:{\1}\t2:{\2}\t3:{\3}\t4:{\4}\t5:{\5}\t6:{\6}\t7:{\7}/g
1:{509} 2:{L.} 3:{Iunius} 4:{Brutus} 5:{L.} 6:{Tarquinius} 7:{Collatinus}
1:{suff.} 2:{Sp.} 3:{Lucretius} 4:{Tricipitinus} 5:{P.} 6:{Valerius} 7:{Poplicola}
1:{suff.} 2:{M.} 3:{Horatius} 4:{Pulvillus} 5:{} 6:{} 7:{}
1:{508} 2:{P.} 3:{Valerius} 4:{Poplicola} 5:{T.} 6:{Lucretius} 7:{Tricipitinus}
1:{507} 2:{P.} 3:{Valerius} 4:{Poplicola} 5:{M.} 6:{Horatius} 7:{Pulvillus}