Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP]Wyrażenia regularne w PHP
Forum PHP.pl > Forum > Przedszkole
Kashikumek
Witam !
Mam taki problem, ponieważ nie wiem jak napisać wyrażenie które bedzie mi pokazywało w pliku test.txt tylko to co wybiore.
Oto kod PHP:
  1. <?php
  2. $strona = file_get_contents('https://twitter.com/test');
  3. echo '<pre>';
  4. preg_match ('/<p class="ProfileTweet-text js-tweet-text u-dir"
  5. lang="it"
  6.  
  7. dir="ltr" data-aria-label-part="0">(.*)<\/p>/s', $strona, $wynik);
  8. //var_dump($wynik);
  9.  
  10. file_put_contents('test.txt', $wynik[0]);
  11. ?>

A tak wygląda wyodrębniona zawartość:
  1. <p class="ProfileTweet-text js-tweet-text u-dir"
  2. lang="it"
  3.  
  4. dir="ltr" data-aria-label-part="0"><a href="/hashtag/A1?src=hash" data-query-source="hashtag_click" class="twitter-hashtag pretty-link js-nav" dir="ltr" ><s>#</s><b>A1</b></a>ABCD</p>

W pliku mam więcej takich "wiadomości" lecz ja chcę aby w pliku test.txt zapisywała się wiadomość o konkretnym hashtagu czyli w tym wypadku A1 czyli wiadomość ABCD i najlepiej bez znaczników HTML..
Wiem , że zapis (.*) pobiera wszystko bez wyjątku..
Czy to w ogóle możliwe ?
Proszę o pomoc w napisaniu wyrażenia regularnego które będzie wyznaczało tylko konkretną wiadomość ..
Comandeer
Skoro to kawałki HTML, to może potraktować to DOM-em? (Ależ ja mam obsesję biggrin.gif)
markuz
Parasowanie HTML-a przy użyciu wyrażeń regularnych nie będzie działać poprawnie (wyjaśnienie).
Proponuję użyć (jak kolega wyżej napisał) np. http://simplehtmldom.sourceforge.net/
nospor
@markuz a to niby czemu? HTML to tekst jak kazdy inny. Jak tylko spelnia szukane wzorce to bedzie działać.
Comandeer
@markuz, @nospor http://forum.php.pl/index.php?showtopic=24...t&p=1158915
Owszem, parsowanie HTML-a regexem przy założeniu, że spełnia on wzorzec jest możliwe… ale stwierdzenie, że HTML (zwłaszcza gdy poczytamy sobie na co pozwala specyfikacja HTML5) spełnia wzorzec to jedynie pobożne życzenie.
Xelah
W pełni zgadzam się z przedmówcą. Owszem, regexpem się da, tylko po co? Muche też można z armaty załatwić...
Po prostu DOM jest szybszy, prostszy i bardziej czytelny. Nie trzeba żadnych zewnętrznych bibliotek. Najprostszy simplexml powinien sobie poradzić. A jak nie to PHP też ma DOM albo ładny obiektowy wrapper fDOMDocument (https://github.com/theseer/fDOMDocument) (ale to już też zakrawa na armatę...)
nospor
Cytat
ale stwierdzenie, że HTML (zwłaszcza gdy poczytamy sobie na co pozwala specyfikacja HTML5) spełnia wzorzec to jedynie pobożne życzenie.
bez zartow... kod html strony nie zmienia się losowa co pol godziny... to jest kod, ktory jest generowany z szablonu i zmienia sie dopiero gdy ktos zmieni szablon wiec naprawde nie wiem o co wam chodzi. Rownie dobrze ktos zmieni szablon i te wasze wszystkie DOMy tez szlag trafi.

Cytat
Muche też można z armaty załatwić...
Ke? Ze niby regexp w porownaniu do DOMa to armata??
Comandeer
Cytat
to jest kod, ktory jest generowany z szablonu

Czasami szablon może się wykrzaczyć z powodu danych z zewnątrz… wink.gif Bardziej chodzi mi raczej o samo traktowanie HTML jako stringa, bo tutaj upatrywałbym całego problemu. HTML to IMO tekstowy zapis przestrzennej struktury, jaką jest DOM i jako taka powinna być traktowana. Chociaż w sumie to już zależy co nas bardziej interesuje: kod jako kod czy to, co ten kod tworzy (bo kod bardzo często może się różnić od tego, co następnie uzyskamy w DOM). Stąd wziął mi się wzór niezgodny ze specką (no nie umiem myśleć o HTML jedynie jako o stringu - być może to już zboczenie wink.gif)

Cytat
Ze niby regexp w porownaniu do DOMa to armata??

Regex jest strasznie low-levelowy… DOM to jednak bardzo pomocna abstrakcja
  1. preg_match('/<div[\s]+id[\s]?=[\s]?['"]?id['"]?[\s]/i', $html);
  2. //vs
  3. $dom->getElementById('id');

Pewnie, można low-levelowo… ale ja tam wybiorę wygodę wink.gif
nospor
Cytat
Czasami szablon może się wykrzaczyć z powodu danych z zewnątrz?
Tak, ale wtedy równie dobrze może szlag trafić Twój DOM, bo zakladasz ze jest tak i tak, a tu nagle ktos daną z zewnatrz zamknie dwa divy, otworzy kolejne o innych klasach i zonk

Cytat
Pewnie, można low-levelowo? ale ja tam wybiorę wygodę
Bys sie nadawał na polityka... podajesz przykłady do o wiele prostrzyszch rzeczy niz mówimy w tym temacie i czym argumentujesz swoją rację wink.gif

W tym temacie nie chodziło o pobranie elementu po ID.
Xelah
Cytat(nospor @ 21.05.2015, 21:20:09 ) *
Ke? Ze niby regexp w porownaniu do DOMa to armata??


Dobrze, nazwijmy to niewłaściwym narzędziem do rozwiązania akurat tego problemu. Jak napisał Comandeer, autor chce parsować DOM a nie string

  1. $html = '<div>
  2. <div>
  3. <p class="ProfileTweet-text js-tweet-text u-dir" lang="it" dir="ltr" data-aria-label-part="0">
  4. <a href="/hashtag/A1?src=hash" data-query-source="hashtag_click" class="twitter-hashtag pretty-link js-nav" dir="ltr" >
  5. <s>#</s>
  6. <b>A1</b>
  7. </a>
  8. ABCD
  9. </p>
  10. </div>
  11. </div>';
  12.  
  13. $doc = new DomDocument();
  14. $doc->loadHTML($html);
  15.  
  16. $xpath = new DOMXpath($doc);
  17. $elements = $xpath->query("//p[contains(concat(' ', @class, ' '), ' ProfileTweet-text ')]//a[contains(@href,'hashtag/A1')]/ancestor::p");
  18.  
  19. echo trim($elements->item(0)->childNodes->item($elements->item(0)->childNodes->length - 1)->textContent);


Wynik:
Kod
ABCD
Kashikumek
Użyłem kodu powyżej ..
CODE

Fatal error: Call to a member function item() on a non-object in /home/u682868681/public_html/index.php on line 70

w czym błąd questionmark.gif
Dodam iż potrzebuje aby "czyste wiadomości" były zapisywane w odrębnym pliku.. co_jest.gif

to jest linijka 70:
Kod
echo trim($elements->item(0)->childNodes->item($elements->item(0)->childNodes->length - 1)->textContent);
Comandeer
@nospor ok, ale nawet przy takiej strukturze mam do wyboru proste relacje albo wzór do całego stringu.
@Kashikumek a co masz w $elements?
Kashikumek
Jeśli chodzi Ci o to :
CODE
$elements = $xpath->query("//p[contains(concat(' ', @class, ' '), ' ProfileTweet-text ')]//a[contains(@href,'hashtag/A1')]/ancestor:tongue.gif");


Dopiero rozpoczynam zabawę z PHP itd .. dlatego piszę to w tym dziale .




Myśle że nie wytłumaczyłem jasno problemu ..
posiadam stronę w której jest kod PHP .. ta strona tworzy mi plik w xml w której są wszystkie wiadomości twittera .. a ja chcę aby w tym pliku albo innym (odrębnym) były tylko wiadomości które posiadają na #A1...

Z góry przepraszam jeśli piszę bzdury..

No dobra a jak by to wyglądało w regexpie ? @nospor
Mógłbyś mi to jakoś objaśnić ?
Xelah
Ktoś się nawet nie raczył pofatygować do dokumentacji, żeby zrozumieć, co się dzieje...

  1. $html = file_get_contents('https://twitter.com/katyperry');
  2.  
  3. $doc = new DomDocument();
  4. @$doc->loadHTML($html);
  5.  
  6. $xpath = new DOMXpath($doc);
  7. $elements = $xpath->query("//p[contains(concat(' ', @class, ' '), ' ProfileTweet-text ')]//a[contains(@href,'hashtag/TheMet?')]/ancestor::p");
  8.  
  9. if($elements->length > 0) {
  10. foreach($elements as $element) {
  11. echo trim($element->textContent). PHP_EOL;
  12. }
  13. }


Poza tym, jesteś świadomy, że strona, którą ładujesz nie zawiera ani jednego elementu z klasą "ProfileTweet-text"?
Wyrażenia regularne w niczym ci nie pomogą. Problem jest w zupełnie innym miejscu... Tam po prostu nie ma tego, czego szukasz... Proponowałbym spróbować ze kontem, na którym są jakieś posty :)
Kashikumek
@Xelah
Zmieniłem stronę i działa .. specool.gif
Lecz jak tą zawartość (wiadomości) zapisać jako plik tekstowy ?,
Pyton_000
np. file_put_contents
Kashikumek
Niestety, taki jest efekt użycia file_put_contents..
CODE
Fatal error: Cannot use object of type DOMElement as array in /home/u682868681/public_html/index.php

facepalmxd.gif worriedsmiley.gif
Xelah
Cytat(Kashikumek @ 25.05.2015, 12:14:39 ) *
Niestety, taki jest efekt użycia file_put_contents..


Z czystej ciekawości, czytałeś może dokumentację do PHP? Coś takiego na prawdę istnieje. Proponuję zacząć od tego, zanim weźniesz się za pisanie jakiego kolwiek kodu.
Polecam zacząć od:
http://php.net/manual/en/langref.php
a potem:
http://php.net/manual/en/funcref.php

Bo niestety widać, że nie zadałeś sobie nawet tyle trudu, żeby przeczytać dokumentację do tego, czego próbujesz użyć. Klepiesz na oślep kod i liczysz na to, że może coś zadziała. A jak nie działa to na forum z kolejnym pytaniem...
Kashikumek
Mówiłem że jestem początkujący i tak, wiem że istnieje dokumentacja PHP .. zapoznaję się z nią krok po kroku .. i to nie jest tak że wale na oślep bo może zadziała, tylko staram się jednak coś zrobić i dopiero gdy już nie mam pojęcia to pytam na forum.. Rozumiem to że przyszedł kolejny "zielony" i chce gotowce.. ale nie ja też staram się czegoś nauczyć .. a że zaczynam przygodę z PHP to robię mnóstwo błędów ...
Staram się szukać, doczytać, popytać ..
Crozin
Po pierwsze nie zaciągaj danych bezpośrednio ze strony Twittera! Przecież ten serwis udostępnia normalne API do wyciągania tego typu informacji: https://dev.twitter.com/rest/public
Próba wyciągania tego z HTML-a bardzo szybko przestanie działać (przecież to jest aktywnie rozwijany serwis), a API pozostanie prawdopodobnie na zawsze niezmienne.
Kashikumek
@Crozin fakt !
Lecz narazie pozostawie to co mam ... tylko potrzebuje pomocy przy pobraniu zawartości do txt..

Problem rozwizany .. poczytałem.. zastanowiłem się i po prostu odnosiłem się nie do tego $ co trzeba .. lecz problem zarzegnany.. temat do zamknięcia. smile.gif
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.