Witam.

Przedstawienie problemu.
Mam taki przykładowy kod strony:
  1. <meta name="keywords" content="" />
  2. <meta name="description" content="" />
  3. <title>tytul</title>
  4. </head>
  5. <div id="gora">
  6. <div id="header">
  7. <div id="logo">
  8. <h1><a href="/">link</a></h1>
  9. <p> tekst</p>
  10. </div>
  11. </div>
  12. </div>
  13. <div id="menu">
  14. <h1><a href="/">link</a></h1>
  15. </div>
  16.  
  17. <div id="page">
  18. <div id="page2">
  19. <div id="page3">
  20. <div id="content">
  21. <div class="post">
  22. <h2 class="title"><a href="#">tekst</a></h2>
  23. <p class="meta">blabla</p>
  24. <div class="tekst">
  25. <p>blablabla</p>
  26. </div>
  27. </div>
  28. <div class="post">
  29. <h2 class="title">tytul</h2>
  30. <div class="entry">
  31. <div class="entry2">
  32. <div class="entry3">
  33. <p>bla bla bla
  34. bla bla bla</p>
  35. </div>
  36. </div>
  37. </div>
  38. </div>
  39. <div class="post">
  40. <h2 class="title"><a href="#">inny tytul</a></h2>
  41. <p class="meta">tekst</p>
  42. <div class="entry">
  43. <p>bla bla bla</p>
  44. </div>
  45. </div>
  46. <div style="srodek">jakis tekst</div>
  47. </div>
  48. <div id="sidebar">
  49. <a href="/">jakies inne</a>
  50. </div>
  51. <div style="srodek">jakis tekst</div>
  52. </div>
  53. </div>
  54. </div>
  55. </div>
  56. <div id="footer-gora">
  57. <div id="footer">
  58. jakas stopka
  59. </div>
  60. </div>
  61. </body>
  62. </html>
Chcę z niego wyciągnąć 3 tagi "div" o klasie "post" wraz z ich zawartością (np. żeby je potem podmienić na coś innego). To znaczy otrzymać:
  1. <div class="post">
  2. <h2 class="title"><a href="#">tekst</a></h2>
  3. <p class="meta">blabla</p>
  4. <div class="tekst">
  5. <p>blablabla</p>
  6. </div>
  7. </div>
  1. <div class="post">
  2. <h2 class="title">tytul</h2>
  3. <div class="entry">
  4. <div class="entry2">
  5. <div class="entry3">
  6. <p>bla bla bla
  7. bla bla bla</p>
  8. </div>
  9. </div>
  10. </div>
  11. </div>
  1. <div class="post">
  2. <h2 class="title"><a href="#">inny tytul</a></h2>
  3. <p class="meta">tekst</p>
  4. <div class="entry">
  5. <p>bla bla bla</p>
  6. </div>
  7. </div>


Próba rozwiązania.
Myślałem, że będą do tego idealne wyrażenia regularne.
Tak więc mały skrypcik w php. Przy prostych tagach niezagnieżdżonych działało dobrze. Ale przy tym już nie.
  1. // wczytanie z pliku itd. wycięte
  2. $tekst = preg_match_all('@<div class="post">.*?(?:<div.*?</div>*?).*?</div>@s', $dane, $matches);
  3. print_r($matches);
I dostaję takie coś:
  1. <div class="post">
  2. <h2 class="title"><a href="#">tekst</a></h2>
  3. <p class="meta">blabla</p>
  4. <div class="tekst">
  5. <p>blablabla</p>
  6. </div>
  7. </div>
  1. <div class="post">
  2. <h2 class="title">tytul</h2>
  3. <div class="entry">
  4. <div class="entry2">
  5. <div class="entry3">
  6. <p>bla bla bla
  7. bla bla bla</p>
  8. </div>
  9. </div>
  1. <div class="post">
  2. <h2 class="title"><a href="#">inny tytul</a></h2>
  3. <p class="meta">tekst</p>
  4. <div class="entry">
  5. <p>bla bla bla</p>
  6. </div>
  7. </div>
Prawie wszystko dobrze oprócz tego drugiego. Otwierają się 4 "div" a zamykają tylko 2.

Winą pewnie jest wyrażenie regularne:
  1. @<div class="post">.*?(?:<div.*?</div>*?).*?</div>@s
Tylko nie wiem co w nim nie tak (miało działać na zasadzie wyszukania tagu "post" i potem w nim zjedzenia innych tagów do takiej samej ilości divów). Bo tak działa, a w jednym miejscu jak obok siebie jest kilka divów to wariuje (na innym przykładzie coś nie działało jak divy były w jednej linii zamykający i otwierający). Próbowałem poprawiać ale nie wychodzi...

Na anglojęzycznych stronach "czytałem", że wyrażenia regularne nie nadają się do parsowania html bo to język nieregularny. I, że lepiej byłoby użyć DOM czy XPath... Tylko, że ja tego nie umiem nic a nic. Jeśli ten problem dało by się rozwiązać DOM to mógłby ktoś podać jakiś prosty przykład z tym związany (bo tak to nawet nie wiem od czego zacząć).

A może ktoś zna po prostu jakiś gotowy program którym można podmienić zawartość znaczników html w kilkuset plikach (zamiast robić to ręcznie)? Niby to tylko potrzebne trochę bardziej rozbudowane "znajdź i zamień"...