Vim实战——匹配自定义的开始标记和结束标记之间的内容
在xml文件中常有许多自定义的标签,这些标签是成对出现的,如<proterty>和</property>,有的时候我们需要操作某个标签对中的内容而又不要引响标签对之外的其他内容,怎么办呢?
下面是xml文件中的一段内容,假如要查找<data>和</data>中的内容,应该用什么表达式才能满中要求呢?
1<cell id="828"> 2 <property name="borderRightWidth">1px</property> 3 <property name="borderTopColor">#000000</property> 4 <property name="borderTopStyle">solid</property> 5 <property name="borderTopWidth">1px</property> 6 <data id="865"> <property name="resultSetColumn">M_MATERIAL_ID</property> </data> 7</cell> 8<cell id="829"> 9 <property name="borderRightWidth">1px</property> 10 <property name="borderTopColor">#000000</property> 11 <property name="borderTopStyle">solid</property> 12 <property name="borderTopWidth">1px</property> 13 <data id="866"> 14 <property name="resultSetColumn">M_NAME</property> 15 </data> 16</cell> 17<cell id="830"> 18 <property name="borderRightWidth">1px</property> 19 <property name="borderTopColor">#000000</property> 20 <property name="borderTopStyle">solid</property> 21 <property name="borderTopWidth">1px</property> 22 <data id="867"> 23 <property name="resultSetColumn">POL_UOM_ID</property> 24 </data> 25</cell> 26<cell id="831"> 27 <property name="borderRightWidth">1px</property> 28 <property name="borderTopColor">#000000</property> 29 <property name="borderTopStyle">solid</property> 30 <property name="borderTopWidth">1px</property> 31 <data id="868"> 32 <property name="resultSetColumn">POL_QTY</property> 33 </data> 34</cell> 35<cell id="832"> 36 <property name="borderRightWidth">1px</property> 37 <property name="borderTopColor">#000000</property> 38 <property name="borderTopStyle">solid</property> 39 <property name="borderTopWidth">1px</property> 40 <data id="869"> 41 <property name="resultSetColumn">POL_UNIT_PRICE</property> 42 </data> 43</cell> 44<cell id="833"> 45 <property name="borderRightWidth">1px</property> 46 <property name="borderTopColor">#000000</property> 47 <property name="borderTopStyle">solid</property> 48 <property name="borderTopWidth">1px</property> 49 <data id="870"> 50 <property name="resultSetColumn">POL_REF_UNIT_PRICE</property> 51 </data> 52</cell> 53<cell id="834"> 54 <property name="borderRightWidth">1px</property> 55 <property name="borderTopColor">#000000</property> 56 <property name="borderTopStyle">solid</property> 57 <property name="borderTopWidth">1px</property> 58 <data id="871"> 59 <structure name="dateTimeFormat"> 60 <property name="category">Long Date</property> 61 <property name="pattern">Long Date</property> 62 </structure> 63 <property name="resultSetColumn">POL_DATE_END</property> 64 </data> 65</cell> |
我想过用/<data.*\/data>来查,但是结果如下:
图1
如图所见只查找出了配对的标签在同一行的情况,而下面的<data>和</data>中分了好几行的情况都没有查到。原因是.匹配的是任意字符,但是不包括行尾符即$符,所以当遇到$后匹配就结束了,应该用\_.来代替.,\_.匹配的是包括行尾符在内的任意字符,似乎这样就行了,结果是不是的呢?看一下… …输入/<data\_.*\/data>
图2
事实上这样一来,匹配的是从第一个<data>到最后一个</data>中的所有内容,vim把第一个<data>和最后一个</data>当作一个标签对了。显然不是我所期望的结果,这时就用到一个有用的东西,叫做匹配尽可能少的字符\{-n,m}当然因为是尽可能少的匹配所以永远不会出现超过一次以上的匹配,所以这里的n,m可以省略,甚至两个都不写只写一个\{-}就行了。
那么就试试看吧… …输入/<data\_.\{-}\/data>
图3
思考:
如何只删除查找到的(即黄色高亮部分的内容)内容?试过加/d,但是删除的只是匹配的第一行的内容
此问题待日后想出解决办法后补上。
~~~~~~~~~~~~~2017.11.15~~~~~~~~~~~~~~
补充:删除黄色高亮部分用替换就可以了,替换成空白,:g :s配合使用,:g/<data\_.\{-}\/data>/s//
水平所限,文中的所写方法并非最简单的,如果您有更好的方法或者有任何问题欢迎留言告知http://yadsun.iteye.com/