соответствие vim для полных html-тегов

#html #vim #tags #match

#HTML #vim #Теги #совпадение

Вопрос:

Адский мир?

 <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>
 

Приведенная выше команда не работает.

Итак, я представил, что был бы счастлив, если бы был какой-нибудь escape-символ, например, ‘ Q’, такой, чтобы ‘ Q’ соответствовал любому полному слову HTML-тега. Здесь тег complete words означает, что

 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
 

Есть ли в vim ‘ Q’ как подстановочный знак?

Если существует подстановочный знак ‘ Q’, то, введя ‘/ Q’, мы можем легко найти не совпадающие теги (то есть не закрытые теги и не открытые теги)

Комментарии:

1. не в состоянии полностью понять ваш вопрос… чтобы немедленно удалить повторяющиеся теги, вы можете использовать :%s/(<[^>]*>)1/1/g

2. Дорогой сандип, я, должно быть, также должен удалить закрывающий тег. Вы удалили только открывающий тег.

3. вы скучали по g флагу? неважно, где находятся теги … <font color=red><font color=red> или </font></font>

4. Дорогой сандип, я пропустил g-флаги. Однако ваша команда не работает для <span a><span a>something <span b><span c>some </span></span>something</span></span>

5. можете ли вы добавить этот пример ввода с ожидаемым результатом к вопросу? так что это поможет другим, пытающимся предложить ответ 🙂

Ответ №1:

Просто для информации.

Я тот человек, который задал выше первоначальный вопрос.

Я написал следующий код.

 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(".")) amp;amp; (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() .