Vim多行匹配以及排除字符串

原文地址:https://blog.zengrong.net/post/1429.html

一个很简单的需求,在下面的XML文件中匹配 <frame> 块。

一开始写了一个:

^\s\+<frame>\_[^\(frame\)]*<\/frame>

这样能达到需求,但是却是凑巧。

因为 [^\(frame\)] 其实并不会匹配一个frame字符串,它依然是将组中的字符串单独对待的。如果在<frame>块之间包含frame中的任何一个字符串,那么匹配就会失败。

凑巧的是,正好在下面的范例中,并没有出现这样的情况。

既然有问题,那么就修改下,最终的版本是这样的:

^\s\+<frame>\(frame\)\@!\_.*<\/frame>

\@! 相当于 perl正则表达式中的 ?!,它的含义是“不匹配一个组”。\@! 后面需要跟 . 来确定匹配范围。为了匹配换行,这里使用了\_.

Vim的正则格式真是不走寻常路啊……无处不在的转义和非转义让人崩溃……

<?xml version="1.0" encoding="UTF-8"?>
<metadata>
  <frames>
	<frame>
	  <x>0</x>
	  <y>0</y>
	  <w>70</w>
	  <h>124</h>
	  <ox>-10</ox>
	  <oy>-1</oy>
	  <ow>70</ow>
	  <oh>124</oh>
	</frame>
	<frame>
	  <x>70</x>
	  <y>0</y>
	  <w>53</w>
	  <h>124</h>
	  <ox>-10</ox>
	  <oy>-2</oy>
	  <ow>53</ow>
	  <oh>124</oh>
	</frame>
	<frame>
	  <x>123</x>
	  <y>0</y>
	  <w>68</w>
	  <f>aaa</f>
	  <h>124</h>
	  <ox>-7</ox>
	  <oy>-2</oy>
	  <ow>68</ow>
	  <oh>124</oh>
	</frame>
	<frame>
	  <x>191</x>
	  <y>0</y>
	  <w>75</w>
	  <h>124</h>
	  <ox>-9</ox>
	  <oy>-2</oy>
	  <ow>75</ow>
	  <oh>124</oh>
	</frame>
	<frame>
	  <x>266</x>
	  <y>0</y>
	  <w>75</w>
	  <h>123</h>
	  <ox>-26</ox>
	  <oy>-3</oy>
	  <ow>75</ow>
	  <oh>123</oh>
	</frame>
  </frames>
</metadata>