How can I make my match non greedy in vim?
我有一个大的HTML文件,它有很多标记,如下所示:
1 2 3 4
| <p class="MsoNormal" style="margin: 0in 0in 0pt;">
<span style="font-size: small; font-family: Times New Roman;">stuff here</span>
</p> |
我正在尝试进行VIM搜索和替换,以摆脱所有的class=""和style="",但我很难让匹配变得不整洁。
我的第一次尝试是
但是Vim似乎不喜欢?。不幸的是,删除?会使匹配变得过于贪婪。
我怎么才能让我的火柴不干净呢?
- 我认为保罗的回答很好。只是说"?"在VIM中不表示可选(如果这是您希望使用"?"实现的目标)
- @LB,多种语言,.*?意思是匹配任何角色但不贪婪。这就是他想要达到的目标。
用.\{-}代替.*。
%s/style=".\{-}"//g
另见:help non-greedy。
- 如果:help non-greedy不起作用,试试:help /\{-。
- 不是很直观,这是只有Vim做的吗?
- 对。vim有自己的正则表达式语言。
- 一切都有自己的正则表达式语言…这是Regex最大的问题之一。
- 许多这些工具都是在同一时间成熟的,并且独立开发了自己的正则表达式语言方言。这些工具中的许多还试图解决不同的问题,因此,在这些实现中,语法可能会有很大的不同,这是有道理的。我们必须承认,这正是现实世界的工作方式,尽管有时候它会让我们作为开发人员的生活更加艰难。幸运的是,现在许多工具至少提供了regex的Perl兼容实现。不幸的是,维姆不是其中之一。
- 如果像我这样的人把搜索结果默认为\v(非常神奇的标志),你就要使用.{-}。
- @shurane@ziggy助记符:控制重复次数,如{1,3}做(大括号)。负号-表示:尽量少重复(little==minus);)
- 我用了无数的regex工具,它们几乎都是一样的。有一种非标准的regex语言是vim的错,而不是regex的错。
- @格伦曼纳,你错了,看看这个答案,看看为什么。
- 相关:在vim wikia搜索多行
- 我在找一个或多个非贪婪的,比如Perl中的/.+?/。帮助文件提供了这个的语法,即.\{-1,}。(1是下限。)
- 为什么我们必须逃离第一个\{,而不是第二个}?
- @克努布是因为同样的原因,当你这样做的时候,你不必两个都逃避,例如,a\{2}。您正在逃离整个{...}原子,而不是单个字符。
- 我可能每周不止读一次这个答案。夸奖!
VIM中的非贪婪搜索是使用-运算符完成的。这样地:
试一试:
怎么了?
- 没有什么!没什么不对劲的!:)
- 不过,为了我自己的利益,我还是想更好地理解那些不听话的事情。
- @马克,只是在我的答案中加了一条注释,说明了"sed&awk"一书中有关regexps的优秀章节。
如果您更熟悉pcre regex语法,那么
是否支持非贪婪运算符?,正如您在OP中所要求的;以及
不需要backwhackgrouping和cardinality操作符(完全违反直觉的vim语法要求,因为您不匹配文字字符,而是指定操作符);以及
您已经用Perl特性编译了[g]vim,使用
:ver和inspect特性;如果有+perl,则可以使用)
尝试使用搜索/替换
例子。交换img标记中的src和alt属性:
1 2 3 4 5 6 7
| <p class="logo"><img src="/caminoglobal_en/includes/themes/camino/images/header_logo.png" alt="">
</p>
:perldo s/(src=".*?")\s+(alt=".*?")/$2 $1/
<p class="logo"><img alt="" src="/caminoglobal_en/includes/themes/camino/images/header_logo.png">
</p> |
- perldo工作得很好,但不幸的是在键入regex时没有突出显示所选的测试。
我发现解决这类问题的一个好办法是:
(如果您愿意,也可以使用Perl)。iow,而不是学习vim的regex特性,使用一个你已经知道的工具。使用Perl会使?修改器工作以取消匹配。
- 很好,但是能够在应用之前执行/pattern以检查模式是否正确匹配,并在vim正则表达式中使用c修饰符也很好:)
- 这是正确的。这里的所有解决方案都不接近非贪婪!如果必须在一行中匹配[0-9]7与大量文本和该模式的多次出现,那么这里没有解决方案可以做到。这里的解决方案只适用于简单的事情(公平地说,就是我们要求的)。但是,如果你在下一个报价之前做的不仅仅是搜索,Vim不会帮你。
plugin eregex.vim处理Perl风格的非贪婪操作符*?和+?。
与\v一起(如几条评论中所建议的那样)
1
| :%s/\v(style|class)\=".{-}"//g |
G'Day.
vim的regexp处理并不太出色。我发现sed的regexp语法与vim的功能完全匹配。
我通常将搜索突出显示设置为(:set hlsearch),然后在输入斜线后使用regexp进入搜索模式。
编辑:马克,最小化贪婪匹配的技巧也在戴尔·杜赫蒂的优秀著作《SED&awk》(消毒的亚马逊链接)中有所介绍。
第三章"理解正则表达式语法"是对与sed和awk有关的更原始的regexp功能的极好介绍。只有一个简短的阅读和强烈推荐。
高温高压
干杯,
- Vim的regex处理实际上相当不错。它可以做SED做不到的事情,比如匹配行/列的数字,或者根据每种语言对字符的分类作为关键字、标识符或空白进行匹配。它还具有零宽度断言和将表达式放在替换项右侧的能力。如果您使用\v,它可以帮助清理大量的语法。
- @布莱恩,干杯。我去帮雷杰克斯看看我错过了什么。