vim匹配完整的HTML标签

时间:2016-10-16 06:22:10

标签: html vim tags match

地狱世界?

<font color=red><font color=red>I am stupid</font></font>

我们可以看到<font color=red>是重复的,所以我可以通过命令删除它

:%s,<font color=red>\(<font color=red>[^<]*</font>\)</font>,\1,g

然而,对于行

<font color=red><font color=red>I am <b>stupid</b>, Huh.</font></font>
<font color=red><font color=red>I am <span style="something"><font color=blue>stupid</font>, Huh.</span></font></font>

上述命令不起作用。

所以我想我会很高兴,如果有一些逃脱角色,例如&#39; \ Q&#39;,那么&#39; \ Q&#39;匹配任何html标签完整的单词。这里,标签完整单词表示

I am <b>stupid</b>, Huh.
I am <span style="something"><font color=blue>stupid</font>, Huh.</span>
I am <br> <font color=red><img src="me.html"></font> <br>
<u><a href="you.html">You</a></u> are <b><font color=red>smarter</font></b> than me

行是标记完整单词,因为上面四行没有不匹配的标记。所有打开的标签都完全关闭,因此,根据我的定义,上面四行是标签完整的单词行。

然后,如果我想删除后续行的前导标记<font color=red>

 <font color=red><font color=red>I am <b>stupid</b>, Huh.</font></font>

我可以使用以下命令。

 :%s,<font color=red>\(<font color=red>\Q*</font>\)</font>,\1,g

有&#39; \ Q&#39;喜欢vim中的外卡?

如果&#39; \ Q&#39;存在外卡,然后输入&#39; / \ Q&#39;我们可以轻松找到不匹配的标签(即非封闭标签和未打开的标签)

1 个答案:

答案 0 :(得分:0)

仅供参考。

我是问过原问题的人。

我写了以下代码。

let g:position=[0,0,0,0]
function! SetQQ(arg_0, arg_1, arg_2, arg_3)
        let g:position[0] = a:arg_0
        let g:position[1] = a:arg_1
        let g:position[2] = a:arg_2
        let g:position[3] = a:arg_3
        call setpos('.', g:position)
endfunction

let     g:xxcmd_find_pair_escape = "normal vat\<ESC>"
let     g:xxcmd_find_pair = "normal vat"
let     g:xxcmd_escape_me = "normal \<Esc>"
let     g:xxcmd_del_out = "normal hda>`<da>"

function! PairOnePrivate(command, pattern)
        let     xxcmd_onn="normal lda>"
        let     xxcmd_all="normal hdat"
        let     s:mycount=0

        let     curr_c = col(".")
        let     my_line = line(".")
        let     cmd_done = 0

        while 1 
                let where_a = match(getline(my_line), a:pattern, curr_c - 1)
                if (where_a < 0 )
                        echo "POP(): NOTHING and BREAK at=" getline(my_line)
                        break
                endif

                let next_search_position = matchend(getline(my_line), a:pattern, curr_c - 1)

                call SetQQ(0, my_line, where_a+1, 0)
                exec g:xxcmd_find_pair_escape

                if ((my_line==line(".")) && (col(".") == where_a+1))
                        let     curr_c = next_search_position
                        exec g:xxcmd_escape_me
                        exec xxcmd_onn
                        echo "POP(): XXX There is no matching tag at line " line(".")
                        break
                endif

                if (a:command == 0)
                        echo "POP(): DELETE ALL"
                        exec xxcmd_all
                        let cmd_done = 1
                else
                        echo "POP(): DELETE OUTER"
                        exec g:xxcmd_del_out
                        let cmd_done = 1
                endif
                let s:mycount += 1
        endwhile 
        return cmd_done
endfunction


function! PairOne(command, pattern)
        let     target = "<.[^>]*"

        if (a:pattern !~ target)
                echo "PairOne(): " a:pattern "args should begin with <"
                return
        endif

        call PairOnePrivate(a:command, a:pattern)
endfunction

每当我想删除以下行的<span>时,

Something <span>something <b>Something</b> Something</span>

我用过

:g/<span>/call PairOne(1, @/)

我想我可以通过更改PairOne()找到原始问题的答案。但我讨厌编码PairOne()