SN@JPER^
10.11.2017, 13:32:39
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?
preg_match_all("'<div id=\"left\" class=\"mb\">(.*?)</div>'is", $html, $matches);
Pyton_000
10.11.2017, 13:41:53
Ł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-parseri wieeele innnych.
SN@JPER^
10.11.2017, 14:04:24
Dzięki za narzędzia! A tak dla samej wiedzy - jest jakaś magiczna sztuczka z regex, która to wyłapie?
Pyton_000
10.11.2017, 14:05:37
Przeczytaj jeszcze raz co napisałem

Nie dociekaj a wyjdziesz na zdrowie
kreatiff
10.11.2017, 15:36:07
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
10.11.2017, 16:31:14
W ogóle tu pojawia się pytanie, co z takimi przypadkami:
class = "mb"
class ="mb"
class= "mb"
class=" mb"
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
10.11.2017, 16:55:33
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
10.11.2017, 17:01:14
ale Wy macie problem. RegExp NIE używa się do parsowania DOM - koniec kropka...
trueblue
10.11.2017, 21:03:38
$html='
<div id="left" class=" mb klasa">1<p>abc</p></div>
<div id="left2" class = "mb klasa">2<p>def</p></div>
<div id="left3" class="mb1 klasa">3<p>ghi</p></div>
<div id="left4" class="mbklasa">4<p>jkl</p></div>';
$dom = new DOMDocument;
$dom->loadHTML($html);
$dom->encoding = 'UTF-8';
$xpath = new DOMXPath($dom);
$divs = $xpath->query('//div[contains(concat(" ",normalize-space(@class)," ")," mb ")]');
foreach($divs as $div){
}
http://kawalekkodu.pl/post/the-tag-is-out-...domxpath-s01e01
SN@JPER^
11.11.2017, 10:40:15
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
11.11.2017, 10:51:49
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.