首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从a到b的最后一次匹配中搜索和替换?

如何从a到b的最后一次匹配中搜索和替换?
EN

Stack Overflow用户
提问于 2015-06-16 12:56:00
回答 2查看 62关注 0票数 1

我有一个胶乳文件,在这个文件中,我想在一个\\之前去掉最后一个\end{quoting}

我正在处理的文件部分看起来类似于以下内容:

代码语言:javascript
复制
\myverse{some text \\
some more text \\}%
%
\myverse{again some text \\
this is my last line \\}%
\footnote{possibly some footnotes here}%
%
\end{quoting}

超过几百行,覆盖了大约50个quoting环境。

我试过使用:%s/\\\\}%\(\_.\{-}\)\\end{quoting}/}%\1\\end{quoting}/gc,但不幸的是,non-greedy量词\{-}还是太贪婪了。它从示例的第二行开始捕获,直到引用环境结束,我猜贪婪的量词会赶上文件中的最后一个\end{quoting}。是否有可能通过搜索和替换来完成此操作,还是应该为此编写一个宏?

编辑:我的预期输出如下所示:

代码语言:javascript
复制
this is my last line }%
\footnote{possibly some footnotes here}%
%
\end{quoting}

(我应该补充说,我现在已经通过编写一个小宏来解决这个任务,但我还是很好奇是否也可以通过搜索和替换来完成。)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-06-16 16:20:11

我认为您试图从\\}%end{quoting}之前的最后一次出现一直到end{quoting},在这种情况下,您不需要任何字符(\_.),您需要“任何不是\\}%的字符”(是的,我知道这不是一个字符,但基本上就是它)。

所以,简单地说(哈!)将您的模式更改为使用\%(\%(\\\\}%\)\@!\_.\)\{-}而不是\_.\{-};这意味着该模式不能包含多个\\}%序列,从而实现您的目标(据我所能确定)。

这使用负零宽度前瞻性模式\@!,以确保对任何字符的下一次匹配限制为不匹配我们希望避免的特定文本(但除此之外,任何其他内容仍然匹配)。有关更多信息,请参见:帮助/零宽度。

也就是说,你的最终命令是:

代码语言:javascript
复制
:%s/\\\\}%\(\%(\%(\\\\}%\)\@!\_.\)\{-}\)\\end{quoting}/}%\1\\end{quoting}/g

(我注意到您的“预期”输出由于某种原因没有包含前几行,它们是被省略了还是命令应该删除它们?)

票数 2
EN

Stack Overflow用户

发布于 2015-06-16 14:15:07

你在正确的轨道上使用非贪婪的多。Vim帮助文件指出,

"{-}“与"*”相同,但使用最短匹配优先算法。

但是,下一行将警告您遇到的问题。

但是:更早开始的匹配比较短的匹配更好:"a{-}b“匹配"xaaab”中的"aaab“。

据我所知,您最好的解决方案是使用宏。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30868222

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档