Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Wyrażenia regularne w preg_match()
Forum PHP.pl > Forum > PHP
qdlaty88
Z kodu html książki telefonicznej chcę wyciągnąć ilość znalezionych pozycji, które zapisane są już na początku dokumentu:

  1. <meta name="description" content="11 256 wyników dla zapytania medycyna"/>


Dokładnie interesuje mnie ciąg znaków "11 256 wyników" i nic poza tym.
Ta liczba jest zależna od kryterium wyszukiwania, dlatego wyrażenie regularne ją odnajdujące powinno wyglądać tak:

  1. (\d+\s)+wyników


Powyższe wyrażenie działa na dostępnych w sieci testerach ale w mojej aplikacji do tablicy zapisuje jedynie "256 wyników" zamiast "11 256 wyników".
Kod odpowiedzialny za wyszukanie i wydruk:

  1. $patternResults = '/(\d+\s)+wyników/';
  2. preg_match($patternResults, $file, $matchesResults);
  3. var_export($matchesResults[0]);


A wydruk to "256 wyników"...
Gdzie się podziały te dwie jedynki?
Dodam, że jeśli tak spreparuję wyrażenie by preg_match() wyszukiwał adresy e-mail, linki do podstron czy liczby obojętnie jakie lub podobnej wielkości co ta z przykładu to wszystko działa. Tylko tej interesującej mnie informacji nie chce przegryźć...
_Borys_
  1. preg_match('/(\d+\s?\d*) wyników/', $file, $matchesResults);
  2. print_r($matchesResults);
  3. echo '<br />'.(int)str_replace(' ', '', $matchesResults[1]);

a gdyby były liczby z kilkoma spacjami to bardziej właściwe będzie
  1. preg_match('/([\d\s]+) wyników/', $file, $matchesResults);
qdlaty88
Niestety tak też nie działa. Na wydruku dostaję:
  1. Array ( [0] => 260 wyników [1] => 260 )
  2. 260

Wciąż brak dwóch pierwszych cyfr.
Jak zmienię kod na:
  1. preg_match_all('/(\d+\s)+/', $file, $matchesResults);

żeby sprawdzić czy w tablicy będzie interesująca mnie wartość, dostaję masę liczb ale nie tą której potrzebuję. Po wydrukowaniu zawartości zmiennej z wczytanym kodem widzę, że pojawia się ona w trzech miejscach. Nie mam już pomysłu jak wyciągnąć ilość wyników...

Zrobiłem to na około wykorzystując takie wyrażenie regularne:
  1. '/content=\".+wyników/'

Dostaję teraz ciąg:
  1. array ( 0 => 'content="11 248 wyników', )

Czyli już prawie to co chciałem (wygląda na to, że przerwa pomiędzy '11' a '248' to nie spacja. Jak to teraz wyczyścić, żeby dostać '11248'?
  1. echo '<br />'.(int)str_replace(' ', '', $matchesResults[0]);

daje na wydruku tylko liczbę '1'...
_Borys_
$matchesResults[1] - tutaj masz samą liczbę ze spacją
Moje też działało, możliwe że jest więcej słów "wyników"
Spróbuj tak
  1. preg_match('/content=\"([\d\s]+) wyników/', $file, $matchesResults);

a str_replace(); tak jak wyżej podałem
qdlaty88
  1. preg_match('/content=\"([\d\s]+) wyników/', $file, $matchesResults);
  2. print_r($matchesResults);
  3. echo '<br />'.(int)str_replace(' ', '', $matchesResults[1]); //To jest linnia 17

Daje na wydruku:
  1. Array ( )
  2. Notice: Undefined offset: 1 in /var/www/pkt_parser/process.php on line 17
  3.  
  4. 0

Sama ilość wyników w całym kodzie powtarza się trzykrotnie w różnym kontekście. Próbowałem już zmieniać ten kontekst. Problem tkwi w tej spacji dzielącej liczbę na dwie części. Jeśli do szukania wykorzystam wyrażenie:
  1. 'content=\"(\d+\s)+'

To dostaję: 'content="11'.
Dla:
  1. '(\d+\s)+wyników'

Mam '248 wyników'.
Wyrażenie:
  1. '(\d+\s)+'

Wyrzuca tablicę pełną różnych liczb znalezionych w kodzie ale nie ma wśród nich tej która jest mi niezbędna.
Ciekawe jest to, że jak wyświetlę źródło strony w przeglądarce i skopiuję interesujący mnie fragment do pliku, który później załaduję do zmiennej za pomocą file_get_contents() to moje wyrażenie działa. Jeśli proces odbywa się automatycznie, czyli pobranie strony, zapis do pliku, pobranie z pliku i przeszukanie to działa jak powyżej...
Kombinuję na wszystkie możliwe sposoby i nic...
_Borys_
Pokaż co zwróciło print_r($matchesResults);
qdlaty88
Tak jak wyżej:
  1. Array ( )

ale jak wyrażenie w preg_match() będzie wyglądać tak: '/content=\".+wyników/' to zwraca:
  1. Array ( [0] => content="11 248 wyników )
_Borys_
A jak wygląda ta linia z liczbą w pliku ?
Spróbuj z modyfikatorem m
  1. preg_match('/content=\"([\d\s]+) wyników/m', $file, $matchesResults);
qdlaty88
  1. <meta name="description" content="11 248 wyników dla zapytania medycyna - znajdź dane firm, adresy i telefony na PKT.PL - największe yellowpages w Polsce. - 1"/>

Problemem jest przerwa pomiędzy '11' a '248'. Wykasowałem tę przerwę i zastąpiłem ją spacją. Wczytałem plik do zmiennej i zatrybiło. Tam jest jakiś śmieć. Tylko jak się go pozbyć skoro nie wiadomo co to jest?
styryl
  1. $string = '<meta name="description" content="11 256 wyników dla zapytania medycyna"/>';
  2.  
  3. $patternResults = '/(\d+?\s(\d+|wyników))/';
  4. preg_match($patternResults, $string, $matchesResults);
  5.  
  6. print_r($matchesResults);
  7.  
qdlaty88
Modyfikator m niestety nic nie zmienia.
_Borys_
  1. preg_match('/content=\"([\d\s]+) wynik/', $file, $matchesResults);

Jeśli to zadziała to masz coś nie tak z kodowaniem pliku.
qdlaty88
Cytat(styryl @ 12.09.2013, 13:34:20 ) *
  1. $string = '<meta name="description" content="11 256 wyników dla zapytania medycyna"/>';
  2.  
  3. $patternResults = '/(\d+?\s(\d+|wyników))/';
  4. preg_match($patternResults, $string, $matchesResults);
  5.  
  6. print_r($matchesResults);
  7.  

Też tak robiłem i działało. Ale u Ciebie w $string pomiędzy '11' a '256' jest spacja, w kodzie jaki pobieram ze strony jest jakiś śmieć...

Cytat(_Borys_ @ 12.09.2013, 13:46:04 ) *
  1. preg_match('/content=\"([\d\s]+) wynik/', $file, $matchesResults);

Jeśli to zadziała to masz coś nie tak z kodowaniem pliku.

Wyrzuca pustą tablicę.
Zostawmy już te wyrażenia. Jeśli wyniku jaki daje mi '/content\"=.+wyników' nie da się wyczyścić to po prostu zrobię tak, że wyszukam najpierw 'content\"=\d+', później '\d+\swyników' i złożę to w jeden ciąg. Przynajmniej pozbędę się tej przerwy i dalej z górki wink.gif
_Borys_
Możesz sobie sprawdzić co tam masz w liczbie
  1. preg_match('/content=\"(.+)\swynik/', $file, $matchesResults);
  2. $cut = str_split($matchesResults[1],1);
  3. foreach($cut as $c){
  4. echo $c.' : '.dechex(ord($c)).'<br />';
  5. }

Wypisuje kolejne znaki z liczby i wartość hex, jeśli trzecia wartość 20 to jest spacja.
Więcej pomysłów nie mam.
qdlaty88
  1. preg_match('/content=\"(.+)\swyników/', $file, $matchesResults);
  2. //print_r($matchesResults);
  3. $cut = str_split($matchesResults[1],1);
  4. foreach($cut as $c){
  5. echo $c.' : '.dechex(ord($c)).'<br />';
  6. }

Daje:
  1. 1 : 31
  2. 1 : 31
  3. &#65533; : c2 // Tu na wydruku jest pytajnik w czarnym rombie.
  4. &#65533; : a0 // Tu też.
  5. 2 : 32
  6. 4 : 34
  7. 8 : 38


Zrobię to tak jak pisałem wcześniej - wyszukując osobno obie części ciągu i później je łącząc.

Cytat(_Borys_ @ 12.09.2013, 14:11:29 ) *
Możesz sobie sprawdzić co tam masz w liczbie
  1. preg_match('/content=\"(.+)\swynik/', $file, $matchesResults);
  2. $cut = str_split($matchesResults[1],1);
  3. foreach($cut as $c){
  4. echo $c.' : '.dechex(ord($c)).'<br />';
  5. }

Wypisuje kolejne znaki z liczby i wartość hex, jeśli trzecia wartość 20 to jest spacja.
Więcej pomysłów nie mam.


To wystarczy smile.gif
Swoim postem podsunąłeś mi rozwiązanie smile.gif
Skoro tam są dwa jakieś znaki to wystarczy zrobić tak:
  1. $patternResults = '/content=\"(\d+.+)+wyników/';
  2. preg_match($patternResults, $file, $matchesResults);
  3. echo '<br />'.(int)preg_replace('#[^0-9.]#', '', $matchesResults[1]);


i mam to co mnie interesuje smile.gif
Dzięki za pomoc biggrin.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.