1

Тема: AHK: Определение закрывающего тега

Существует ли способ в HTML-коде без подсчетов всех тегов и т.п. - определить парный тег какого-либо тега? На скрине такой пример - https://i.imgur.com/qYw5i3x.jpg.

2

Re: AHK: Определение закрывающего тега

Думаю, алгоритм такой.
После открывающего <div> ищем закрывающий </div>, либо другие открывающие <div>. Заведём переменную "n", первоначально присвоив ей значение "0".
Если по пути попался открывающий <div>, то прибавим к "n" единичку.
Если по пути попался закрывающий </div>, то вычтем из "n" единичку.
И так далее, пока n не станет равным нулю. Как только станет равным нулю, начит это закрывающий </div> от самого первого открывающего <div>.  https://i.smiles2k.net/aiwan_smiles/wink.gif

3

Re: AHK: Определение закрывающего тега

Посмотрите алгоритмы на правильность скобок на JS. Думаю не сложно будет перевести под теги.

Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)

4 (изменено: john_dease, 2023-05-07 14:08:03)

Re: AHK: Определение закрывающего тега

Вроде получилось сделать с перебором тегов (выводит закрывающий тег с пробелом "</div >"). А как сходу захватить найденное?

div =
(
<div class="tweet-body">
  <div><div class="tweet-header">
      <a class="tweet-avatar" href="/GoITO"><img class="avatar round" src="/pic/profile_images%2F1601252088977461249%2FAueLzD04_bigger.jpg" alt="" /></a>
      <div class="tweet-name-row">
        <div class="fullname-and-username">
          <a class="fullname" href="/GoITO" title="伊藤剛">11</a>
          <a class="username" href="/GoITO" title="@GoITO">@11</a>
        </div>
        <span class="tweet-date"><a href="/" title="May 3, 2023 · 4:48 PM UTC">May 3</a></span>
      </div>
    </div></div>
  <div class="tweet-content media-body" dir="auto">1999</div>
  <div class="tweet-stats">
    <span class="tweet-stat"><div class="icon-container"><span class="icon-comment" title=""></span> 2</div></span>
    <span class="tweet-stat"><div class="icon-container"><span class="icon-retweet" title=""></span> 110</div></span>
    <span class="tweet-stat"><div class="icon-container"><span class="icon-quote" title=""></span> 1</div></span>
    <span class="tweet-stat"><div class="icon-container"><span class="icon-heart" title=""></span> 332</div></span>
  </div>
</div|1></div></span>
  </div>
<div class="tweet-body"><div class="icon-container">22 332</div></div|2>
)

Pos := 0, n := 0
While Pos := RegExMatch(div, "s)</?div\b[^>]*>", match, Pos + 1)
{
   If (match~="<[^/]")
      n+=1
   If (match~="</")
      n-=1
   If (n=0) {
      msgbox %match% %n%
      break
   }
}

5

Re: AHK: Определение закрывающего тега

Всё-таки, не работает. Видимо, While не подходит для этой задачи.

6

Re: AHK: Определение закрывающего тега

Как понять "захватить найденное"? Требуется поместить в переменную всё то, что лежит между первым открывающим <div> и евоным закрывающим </div>?

7

Re: AHK: Определение закрывающего тега

Да. Но в коде выше не учтено, что нужен не любой div, а с определенным классом. То есть, видимо надо сначала получить кусок от заданного тега до конца фрагмента, а уже потом подсчитывать.

8

Re: AHK: Определение закрывающего тега

Пробегайтесь регуляркой от <div class="tweet-body"> до <div class="tweet-body">.
Считать div тут не нужно.

9

Re: AHK: Определение закрывающего тега

Как-то можно узнать позицию в тексте для первого открывающего <div> и последнего закрывающего </div>. (Только я подзабыл как. https://i.smiles2k.net/aiwan_smiles/meeting.gif)
Из позиции последнего вычитаем позицию первого - получаем длину интересующего нас фрагмента. Потом считываем (тоже подзабыл, вроде командой SubStr()) в переменную блок символов, начиная с позиции первого открывающего <div> и длиной, равной длине интересующего нас фрагмента. Таким образом в переменной окажется блок, который требовалось захватить.

10 (изменено: john_dease, 2023-05-07 12:24:13)

Re: AHK: Определение закрывающего тега

Malcev

Но так последний <div class="tweet-body"> будет пропущен? Ведь после него не будет такого же тега? А еще между <div class="tweet-body">(.+?)</div> могут быть другие лишние теги.

11 (изменено: john_dease, 2023-05-07 12:44:30)

Re: AHK: Определение закрывающего тега

Видимо, тут нужен перебор по другому такому же тегу, либо концу вхождения. После чего уже разбирать найденное.

Pos := 0, n := 0
While Pos := RegExMatch(div, "s)(<div class=""tweet-body"">)(.*?)(\1|$)", match, Pos + 1)
{
    msgbox %match1%%match2%
}

12

Re: AHK: Определение закрывающего тега

Теперь вроде перебирает и обрабатывает:

div =
(
              <div class="tweet-body">
                <div><div class="tweet-header">
                    <a class="tweet-avatar" href="/GoITO"><img class="avatar round" src="/pic/profile_images%2F1601252088977461249%2FAueLzD04_bigger.jpg" alt="" /></a>
                    <div class="tweet-name-row">
                      <div class="fullname-and-username">
                        <a class="fullname" href="/GoITO" title="伊藤剛">11</a>
                        <a class="username" href="/GoITO" title="@GoITO">@11</a>
                      </div>
                      <span class="tweet-date"><a href="/" title="May 3, 2023 · 4:48 PM UTC">May 3</a></span>
                    </div>
                  </div></div>
                <div class="tweet-content media-body" dir="auto">1999</div>
                <div class="tweet-stats">
                  <span class="tweet-stat"><div class="icon-container"><span class="icon-comment" title=""></span> 2</div></span>
                  <span class="tweet-stat"><div class="icon-container"><span class="icon-retweet" title=""></span> 110</div></span>
                  <span class="tweet-stat"><div class="icon-container"><span class="icon-quote" title=""></span> 1</div></span>
                  <span class="tweet-stat"><div class="icon-container"><span class="icon-heart" title=""></span> 332</div></span>
                </div>
              </div|1></div></span>
                </div>
              <div class="tweet-body"><div class="icon-container">22 332</div></div|2>
)

Pos := 0
While Pos := RegExMatch(div, "s)(<div class=""tweet-body"">)(.*?)(\1|$)", match, Pos + 1)
{
    new_div := match1 match2

    Poss := 0, n := 0
    While Poss := RegExMatch(new_div, "s)</?div\b[^>]*>", match, Poss + 1)
    {
       ;msgbox %match%
       If (match~="<[^/]")
          n+=1
       If (match~="</")
          n-=1
       If (n=0) {
          msgbox %match% %n%
          break
       }
    }
}

13

Re: AHK: Определение закрывающего тега

Но опять же, проблема с захватом найденного.

14 (изменено: john_dease, 2023-05-08 04:51:09)

Re: AHK: Определение закрывающего тега

Вот вариант с авто-определением тега и перебором:

DivFrag =
(
<div class="tweet-body">
  <div><div class="tweet-header">
      <a class="tweet-avatar" href="/GoITO"><img class="avatar round" src="/pic/profile_images%2F1601252088977461249%2FAueLzD04_bigger.jpg" alt="" /></a>
      <div class="tweet-name-row">
        <div class="fullname-and-username">
          <a class="fullname" href="/GoITO" title="伊藤剛">11</a>
          <a class="username" href="/GoITO" title="@GoITO">@11</a>
        </div>
        <span class="tweet-date"><a href="/" title="May 3, 2023 · 4:48 PM UTC">May 3</a></span>
      </div>
    </div></div>
  <div class="tweet-content media-body" dir="auto">1999</div>
  <div class="tweet-stats">
    <span class="tweet-stat"><div class="icon-container"><span class="icon-comment" title=""></span> 2</div></span>
    <span class="tweet-stat"><div class="icon-container"><span class="icon-retweet" title=""></span> 110</div></span>
    <span class="tweet-stat"><div class="icon-container"><span class="icon-quote" title=""></span> 1</div></span>
    <span class="tweet-stat"><div class="icon-container"><span class="icon-heart" title=""></span> 332</div></span>
  </div>
</div>
11
<div class="tweet-body"><div class="icon-container">22 332</div></div>
)

document := ComObjCreate("HTMLFile")
document.write(DivFrag)

elements := document.getElementsByClassName("tweet-body")
loop, % elements.length
   msgbox, % elements[A_Index-1].outerHTML

15

Re: AHK: Определение закрывающего тега

В предыдущем сообщении перебирается тег с одним классом, а как одновременно перебирать теги с двумя разными классами, как в примере?

RTxt=
(
<div class="timeline-item ">
              <a class="tweet-link" href="/htGOIW/status/1503785730207793159#m"></a>
              <div class="tweet-body">
                <div><div class="tweet-header">
                    <a class="tweet-avatar" href="/htGOIW"><img class="avatar round" src="/pic/profile_images%2F1633116033539096585%2FA_O5JZKS_bigger.jpg" alt="" /></a>
                    <div class="tweet-name-row">
                      <div class="fullname-and-username">
                        <a class="fullname" href="/htGOIW" title="ehoba">ehoba</a>
                        <a class="username" href="/htGOIW" title="@htGOIW">@htGOIW</a>
                      </div>
                      <span class="tweet-date"><a href="/htGOIW/status/1503785730207793159#m" title="Mar 15, 2022 · 5:30 PM UTC">15 Mar 2022</a></span>
                    </div>
                  </div></div>
                <div class="tweet-content media-body" dir="auto">The interesting thing is that they can do the same thing with Japanese myths too. Daijiro Morohoshi did it, and that's
one of NGE's direct inspiration sources.
I suppose the attitudes towards religions in general affect that difference.</div>
                <div class="tweet-stats">
                  <span class="tweet-stat"><div class="icon-container"><span class="icon-comment" title=""></span> 1</div></span>
                  <span class="tweet-stat"><div class="icon-container"><span class="icon-retweet" title=""></span> 1</div></span>
                  <span class="tweet-stat"><div class="icon-container"><span class="icon-quote" title=""></span></div></span>
                  <span class="tweet-stat"><div class="icon-container"><span class="icon-heart" title=""></span> 4</div></span>
                </div>
              </div>
            </div>
)
document := ComObjCreate("HTMLFile")
document.write(RTxt)

elements1 := document.getElementsByClassName("icon-comment")
elements2 := document.getElementsByClassName("icon-retweet")
loop, % elements.length
{
   e1 := % elements1[A_Index-1].outerHTML
   e2 := % elements2[A_Index-1].outerHTML

   msgbox %e1%`n%e2%
}

16

Re: AHK: Определение закрывающего тега

Осуществимо ли следующее для данного кода или другого метода - теги с классом "tweet-body" из переменной HTMLvar перебираются, и во время этого перебора переменная HTMLvar дополняется новым тегом (символ "|" заменяется на новый тег), который тоже должен попасть в перебор?

HTMLvar =
(
<div class="tweet-body"><div class="icon-container">111</div></div>
<div class="tweet-body"><div class="icon-container">222</div></div>
<div class="tweet-body"><div class="icon-container">333</div></div>
<div class="tweet-body"><div class="icon-container">444</div></div>
<div class="tweet-body"><div class="icon-container">555</div></div>|
)

document := ComObjCreate("HTMLFile")
document.write(HTMLvar)

elements := document.getElementsByClassName("tweet-body")
loop, % elements.length
{
   tag := % elements[A_Index-1].outerHTML ;outerHTML/innerText
   StringReplace, HTMLvar, HTMLvar, |, <div class="tweet-body"><div class="icon-container">666</div></div>, All
   msgbox % tag
}

17

Re: AHK: Определение закрывающего тега

То есть, как перебирать теги из дополняемой переменной.

18

Re: AHK: Определение закрывающего тега

Пока что такой вариант: в переменной var1 определяются границы нужных тегов, после чего происходит перебор этих тегов в "While Pos". В процессе перебора переменная var1 дополняется переменной var2, в которой так же определяются границы тегов, выводимые в качестве продолжения. Но получилось не юзабельно, может, можно упростить.

var1 =
(
<div class="tweet-body"><div class="icon-container">111</div></div>
44
<div class="tweet-body"><div class="icon-container">222</div></div>
<div class="tweet-body"><div class="icon-container">333</div></div>
<div class="tweet-body"><div class="icon-container">444</div></div>
<div class="tweet-body"><div class="icon-container">555</div></div>|
)

var2 =
(
<div class="tweet-body"><div class="icon-container">666</div></div>
)

document := ComObjCreate("HTMLFile")
document.write(var1)

elements := document.getElementsByClassName("tweet-body")
loop, % elements.length
{
   tag := % elements[A_Index-1].outerHTML ;outerHTML/innerText
   StringReplace, var1, var1, %tag%, <%tag%>, All
}

;msgbox % var1

match := "", match1 := "", Pos := 0
While Pos := RegExMatch(var1, "s)<(<[^>]*class=""tweet-body"".*?</div>)>", match, Pos + 1)
{
   document := ComObjCreate("HTMLFile")
   document.write(var2)

   elements := document.getElementsByClassName("tweet-body")
   loop, % elements.length
   {
      tag := % elements[A_Index-1].outerHTML ;outerHTML/innerText
      StringReplace, var2, var2, %tag%, <%tag%>, All
   }

   StringReplace, var1, var1, |, %var2%, All

   msgbox % match1
}

19

Re: AHK: Определение закрывающего тега

Обязательно ли объявлять

document := ComObjCreate("HTMLFile")

каждый раз, или можно один раз?