Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Regex - łapanie odpowiednich tagów zamykających
Forum PHP.pl > Forum > PHP
SN@JPER^
Witam.

Mam taki kod, którym próbuję wyciągnąć dane pomiędzy tym divem. Jednak w tym divie są inne divy i kończy "łapanie" na pierwszym napotkanym, zamykającym </div>. Jak mogę zrobić, aby rozpoznawało tag odpowiednio zamykający?

  1. preg_match_all("'<div id=\"left\" class=\"mb\">(.*?)</div>'is", $html, $matches);
Pyton_000
Łapy się obcina za parsowanie HTML przy pomocy RegEx...

Do tego są odpowiednie narzędzia np:
http://simplehtmldom.sourceforge.net/
https://github.com/sunra/php-simple-html-dom-parser

i wieeele innnych.
SN@JPER^
Dzięki za narzędzia! A tak dla samej wiedzy - jest jakaś magiczna sztuczka z regex, która to wyłapie?
Pyton_000
Przeczytaj jeszcze raz co napisałem wink.gif Nie dociekaj a wyjdziesz na zdrowie smile.gif
kreatiff
W (.*?) masz łapanie leniwe (lazy, czyli łapanie najmniej jak się da), właśnie przez ten znak zapytania. Usuń go, a dopasowywanie zmieni się w zachłanne (greedy, dopasuj maksymalnie dużo).
Możesz też użyć modyfikatora U, który zmienia (odwraca) zachłanność wzoru, bez usuwania tego znaku zapytania.

W wyniku wyrażenia regularnego nadal będziesz musiał pozbyć się nadliczbowych znaczników <div>.
trzczy
W ogóle tu pojawia się pytanie, co z takimi przypadkami:

  1. class = "mb"
  2. class ="mb"
  3. class= "mb"
  4. class=" mb"
  5. class = "foo mb"


Klasa może być na wiele sposobów przypisana. Czy regex ma je wszystkie uwzględniać? Zatem w przypadku regex, trzeba wiedzieć, jaki to skomplikowany problem.
kreatiff
Można pominąć całkiem, skoro nie jest to w ogóle potrzebne: '#<div.*?>(.*?)</div>#is'.

ed. chyba. że chodzi ci o divy z tą konkretną klasą "mb", to wówczas można kombinować:
'#<div.*?class=".*?mb.*?".*?>(.*?)</div>#is'

Ale to może się okazać ślepym zaułkiem.
Pyton_000
ale Wy macie problem. RegExp NIE używa się do parsowania DOM - koniec kropka...
trueblue
  1. $html='
  2. <div id="left" class=" mb klasa">1<p>abc</p></div>
  3. <div id="left2" class = "mb klasa">2<p>def</p></div>
  4. <div id="left3" class="mb1 klasa">3<p>ghi</p></div>
  5. <div id="left4" class="mbklasa">4<p>jkl</p></div>';
  6.  
  7. $dom = new DOMDocument;
  8. $dom->loadHTML($html);
  9. $dom->encoding = 'UTF-8';
  10. $xpath = new DOMXPath($dom);
  11. $divs = $xpath->query('//div[contains(concat(" ",normalize-space(@class)," ")," mb ")]');
  12. foreach($divs as $div){
  13. echo $div->textContent;
  14. }


http://kawalekkodu.pl/post/the-tag-is-out-...domxpath-s01e01
SN@JPER^
To może lepsze pytanie - które narzędzie wybrać?

DOMXPath, php-simple-html-dom-parser, phpquery lub inne? Które jest najaktualniejsze, ma wsparcie i najczęściej się używa?
trueblue
Klasy DOMDocument i DOMXPath bazują na rozszerzeniu libxml, który jest częścią kompilacji PHP (najczęściej jest). Czyli są naturalną częścią PHP. XPath ma na pewno większe możliwości niż SimpleHTMLDom, co do PHPQuery, to wydaje mi się, że jeśli chodzi o selektory, to ciut większe. Zapis XPath może być trochę zniechęcający, ale możliwości spore.
Ale to zależy od Ciebie.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.