我的问题是关于非常具体的搜索和替换模式,但我希望找到更一般情况的答案。我目前正在处理一些带有分配叠加的LaTeX幻灯片,我需要将某些整数增加一个或多个。示例文本:
\only<1,5-7,9>{hello 11}
简而言之, only 命令仅在幻灯片编号1,5到7和9上显示 hello 11 。在位置2插入幻灯片后,我需要所有幻灯片上面的幻灯片2增加。这就是我想出的:
:.,$s/\d\+/\=str2float(submatch(0))>2?submatch(0)+1:submatch(0)/g
从当前行到文件末尾,它将所有整数增加到2以上1.这意味着11也会递增,这不是我想要的:
\only<1,6-8,10>{hello 12}
Q1 :我怎样才能匹配和增加分隔符'&lt;'之间的整数和'&gt;'?
最终,我希望能够通过指定模式并将另一种模式应用于结果来逐步优化搜索模式。例如,我首先匹配给定示例文本中的分隔符之间的文本。
/<[^<>]*>
这将突出我引用的文字:
\only"<1,5-7,9>"{hello 11}
现在应用我原来的解决方案来增加分隔符之间的数字。我可以通过管道符号在一个shell中将 grep 命令链接在一起来比较我想要做的事情,用每个新的grep命令改进结果。
Q2:这个链接的vim搜索模式是否可行?
更新: Floris的解决方案非常接近。确实它解决了原始问题,但我没有提到所有要求。他们是:
- The delimiters are guaranteed to be on one line, e.g., <1,5-7,9>.
- Multiple delimited parts can be on one line, e.g.:
hello 11\only<1,6-7,9>{hello 11}\only<1,6-7,9>{hello 11}
第二个要求失败,因为解决方案当前返回:
hello 12\only<1,7-8,10>{hello 12}\only<1,7-8,10>{hello 11}
它只在最后一次出现'&gt;'后忽略整数。我希望结果如下:
hello 11\only<1,7-8,10>{hello 11}\only<1,7-8,10>{hello 11}
感谢您的帮助!
答案 0 :(得分:2)
你需要一个lookahead
构造 - 我认为它如下:
:.,$s/[0-9]\+\(.*>\)\@=/\=str2float(submatch(0))>2?submatch(0)+1:submatch(0)/g
我添加的是
\(.*>\)\@=
这是一个“积极向前看”,一个零宽度断言,说
之前的事情必须跟随任意数量的字符,然后是紧密括号
您可以在vim帮助中找到有关语法的更多信息,或https://stackoverflow.com/a/18391881/1967396(我从中得到它)。
运行上面的内容,我确实得到了
\only<1,6-8,10>{hello 11}
作为输出 - 这是我认为你想要的。
注意:我在Mac上vim
进行了测试。众所周知,它的行为与linux版本略有不同(好吧,我从sed
差异推断,我实际上知道 vim
也不同......)如果这不起作用,它应该是快活的。
答案 1 :(得分:1)
您基本上只需要在某些地方(即<...>
部分内)应用搜索和替换(带有可以评估条件的表达式!)。
这很难,因为你需要:
<...>
,并在内部执行另一个替换,Vim不允许(递归 sub-replace-expression (\=...
)是不可能的) PatternsOnText plugin的新版本1.30可以处理此问题:
首先,搜索<...>
位置:
/<[^>]\+>
然后,制定一个仅在搜索结果中应用的特殊替换:
:%SubstituteInSearch/\d\+/\=submatch(0) > 2 ? submatch(0) + 1 : submatch(0)/g
答案 2 :(得分:0)
如果你可以认为\only<....
会出现在它自己的一行上,你可以简单地
:.,$g/\\only<\d/s/\d\+/\=str2float(submatch(0))>2?submatch(0)+1:submatch(0)/g
这是:global
命令(:.,$g/\\only<\d/
)用于过滤目标行,然后你的“魔法”替换未改变:)
答案 3 :(得分:0)
关于正则表达式的问题当然是相关的,但是关于你太多的叠加,也许你应该考虑使用名字而不是数字:Tex-Latex的解决方案可以在:
https://tex.stackexchange.com/questions/34458/reference-overlay-numbers-with-names?rq=1