Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [PHP]Problem z preg_match_all
Ulysess
post
Post #1





Grupa: Zarejestrowani
Postów: 695
Pomógł: 65
Dołączył: 27.07.2009
Skąd: Y

Ostrzeżenie: (0%)
-----


dobry wieczór , mam oto taki skrypt:
  1. <?php
  2.  
  3. $page = file_get_contents("old/page.txt");
  4.  
  5. echo '<table>
  6. <tr>
  7. <td></td>
  8. <td></td>
  9. <td></td>
  10. <td></td>
  11. <td></td>
  12. <td></td>
  13. <td></td>
  14. </tr>';
  15.  
  16. preg_match_all('#<a href="#" onClick="window.open(\'gildia_informacje.php?id=(.*)\',\'Informacje\',\'width=550,height=810,top=0,left=0,scrollbars=yes,\');" style="font-size: 13px; color: #BFAC2B; font-weight: bold;">(.*)</a></b></td>
  17. <td background="images/tabelka_metalowa/prawa.jpg" width="11" align="center" ></td>
  18. </tr>
  19. <tr>
  20. <td></td>
  21. <td width="120" align="center" valign="top"><img border="1" src="(.*)"><br>(.*)</td>
  22. <td valign="top" height="40">
  23. <b style="font-size: 18px; color: darkred;">(.*)</b> -
  24. <b style="font-size: 12px; color: green;">(.*)</b>
  25. <div align="left">Szacunek: <b>(.*)</b><br>Liczba członków: <b>(.*)</b>#', $page, $matches);
  26.  
  27. $length = count($matches[0]);
  28. echo $length;
  29. for ( $i = 0; $i < $length; $i++ )
  30. {
  31. echo '<tr>';
  32. echo '<td>'.$matches[0][$i].'</td>';
  33. echo '<td>'.$matches[1][$i].'</td>';
  34. echo '<td>'.$matches[2][$i].'</td>';
  35. echo '<td>'.$matches[3][$i].'</td>';
  36. echo '<td>'.$matches[4][$i].'</td>';
  37. echo '<td>'.$matches[5][$i].'</td>';
  38. echo '<td>'.$matches[6][$i].'</td>';
  39. echo '</tr>';
  40. }
  41.  
  42. echo '</table>';
  43.  
  44. ?>


jego zadaniem jest otworzyć dokument page.txt i wyciągnąć interesujące mnie dane które podałem w modelu. Problem polega na tym że wywala "
Warning: preg_match_all() [function.preg-match-all]: Unknown modifier '"' in E:\VertrigoServ\www\skrypt.php on line 25"

nie mam zielonego pojęcia o co mu chodzi..
Go to the top of the page
+Quote Post
Valdi_B
post
Post #2





Grupa: Zarejestrowani
Postów: 107
Pomógł: 30
Dołączył: 19.02.2011
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


W wyrażeniu regułowym (1-szym argumencie preg_match) jako ograniczniki użyłeś znaku "#".
Kolizja polega na tym, że znak "#" masz w środku tego wyrażenia.

Metoda 1. Zmień ograniczniki na jakieś inne.
Metoda 2. Poprzedź ten "środkowy #" znakiem "\".

Co do met. 2 nie jestem do końca pewny, ale sprawdź i odpisz.

Edit:
W treści wzorca masz w 8 miejscach sekwencje "(.*)" - jak widać - subwzorce przechwytywane.
Zwróć jednak uwagę, że masz tam także nawiasy wokół argumentów funkcji window.open.
Dla preg_match te nawiasy TAKŻE będą ogranicznikami subwzorca, a to chyba nie to, czego chcesz.
Być może oba te nawiasy też musisz poprzedzić znakiem "\".

Ten post edytował Valdi_B 5.03.2011, 21:25:25
Go to the top of the page
+Quote Post
zegarek84
post
Post #3





Grupa: Zarejestrowani
Postów: 1 332
Pomógł: 294
Dołączył: 12.10.2008
Skąd: Olkusz

Ostrzeżenie: (0%)
-----


metoda druga także pozwoli ominąć błąd... jednak ZONK'a wciąż będzie miał przez pójście na łatwiznę bez zrozumienia wyrażeń regularnych i przekopiowanie kodu HTML na żywca do ciągu... dla przykładu fragment z brzegu: gildia_informacje.php?id - co może oznaczać także "gildia_informacjeFphid" lub "gildia_informacje.phpid" ale za czorta nie dopasuje się do "gildia_informacje.php?id" - jakie jest znaczenie kropki w wyrażeniach regularnych?? - dowolny jeden znak - no prawie dowolny - nie ma w nim definicji bodajże nowej linii i kilku innych - znaczenie znaku zapytania znaczy tyle co zapis {0,1} -> czyli możliwe wystąpienie 0 lub jeden poprzedzający znak - dalej nie chce mi się komentować... a do parsowania dokumentów HTML lepiej skozystać z DOM lub wpisać w google PHPQuery - jest to nakładka na DOM pozwalająca na korzystanie z selektorów jak w jQuery zwracająca elementy DOM - po więcej odsyłam do manuala php czy to o wyrażenia regularne czy o wspomniany DOM...

a propo wyrażeń regularnych to każdy ze znaków specjalnych trzeba poprzedzić znakiem "\"

Ten post edytował zegarek84 5.03.2011, 21:33:12
Go to the top of the page
+Quote Post
Fifi209
post
Post #4





Grupa: Zarejestrowani
Postów: 4 655
Pomógł: 556
Dołączył: 17.03.2009
Skąd: Katowice

Ostrzeżenie: (0%)
-----


Najprościej preg_quote

Cytat(zegarek84 @ 5.03.2011, 21:31:54 ) *
jakie jest znaczenie kropki w wyrażeniach regularnych?? - dowolny jeden znak - no prawie dowolny - nie ma w nim definicji bodajże nowej linii i kilku innych -

Zależnie od Flag o czym mówi manual:
Cytat
If this modifier is set, a dot metacharacter in the pattern matches all characters, including newlines. Without it, newlines are excluded. This modifier is equivalent to Perl's /s modifier. A negative class such as [^a] always matches a newline character, independent of the setting of this modifier.

http://pl2.php.net/manual/pl/reference.pcr...n.modifiers.php
Go to the top of the page
+Quote Post
Ulysess
post
Post #5





Grupa: Zarejestrowani
Postów: 695
Pomógł: 65
Dołączył: 27.07.2009
Skąd: Y

Ostrzeżenie: (0%)
-----


próbuje w sposób następujący:

  1. <?php
  2.  
  3. $page = file_get_contents("old/page.txt");
  4.  
  5. preg_match_all('~<table width="95%" cellpadding="4" cellspacing="0" border="0" align="center">
  6. <tr>
  7. <td background="images/tabelka_metalowa/lewa.jpg" width="11" align="center" ></td>
  8. <td class="tlo-g" colspan="2" align="center"><b><a href="#" onClick="window.open\(\'gildia_informacje.php?id=(.*)\',\'Informacje\',\'width=550,height=810,top=0,left=0,scrollbars=yes,\'\);" style="font-size: 13px; color: #BFAC2B; font-weight: bold;">(.*)</a></b></td>
  9. <td background="images/tabelka_metalowa/prawa.jpg" width="11" align="center" ></td>
  10. </tr>
  11. <tr>
  12. <td></td>
  13. <td width="120" align="center" valign="top"><img border="1" src="obrazkigildii/(.*)"><br>(.*)</td>
  14. <td valign="top" height="40">
  15. <b style="font-size: 18px; color: darkred;">(.*)</b> -
  16. <b style="font-size: 12px; color: green;">(.*)</b>
  17.  
  18. <div align="left">Szacunek: <b>(.*)</b><br>Liczba członków: <b>(.*)</b><br><b>.*</b><br>Wymagany poziom: <b>.*</b></div><b>Regulamin:</b><br>.*</td>
  19. <td></td>
  20. </tr>
  21. <tr>
  22. <td background="images/tabelka_drewniana/lewa.jpg" align="center"></td>
  23. <td class="tlo-z" align="center">-</td>
  24. <td class="tlo-z"></td>
  25.  
  26. <td background="images/tabelka_drewniana/prawa.jpg" width="11" align="center" ></td>
  27. </tr>
  28. </table>~', $page, $matches);
  29.  
  30.  
  31. print_r($matches);
  32.  
  33. $suma = count($matches);
  34.  
  35. print_r($suma);
  36.  
  37. echo '<table>
  38. <tr>
  39. <td></td>
  40. <td></td>
  41. <td></td>
  42. <td></td>
  43. <td></td>
  44. <td></td>
  45. <td></td>
  46. </tr>';
  47.  
  48. for ( $i = 0; $i < $suma; $i++ )
  49. {
  50. echo '<tr>';
  51. echo '<td>'.$matches[0][$i].'</td>';
  52. echo '<td>'.$matches[1][$i].'</td>';
  53. echo '<td>'.$matches[2][$i].'</td>';
  54. echo '<td>'.$matches[3][$i].'</td>';
  55. echo '<td>'.$matches[4][$i].'</td>';
  56. echo '<td>'.$matches[5][$i].'</td>';
  57. echo '<td>'.$matches[6][$i].'</td>';
  58. echo '</tr>';
  59. }
  60.  
  61. echo '</table>';
  62.  
  63. ?>


zmienna matches zawiera Array ( [0] => Array ( ) [1] => Array ( ) [2] => Array ( ) [3] => Array ( ) [4] => Array ( ) [5] => Array ( ) [6] => Array ( ) [7] => Array ( ) [8] => Array ( ) ) 9

a nie o to przecież chodziło ...
Go to the top of the page
+Quote Post
Valdi_B
post
Post #6





Grupa: Zarejestrowani
Postów: 107
Pomógł: 30
Dołączył: 19.02.2011
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Fifi209 dobrze poradził, abyś użył funkcji preg_quote, która poprzedzi znakiem "\" każdy znak specjalny w wyrażeniach regułowych.
Skoro jednak nie chcesz tak zrobić, to przynajmniej postaw "\" przed "?" (który też ma specjalne znaczenie w wyrażeniach regułowych).

Edit:
Jak spowodować, aby wyrażenie regułowe nie było tak długie:
Popatrz na taki przykład:

$wyr = '\?id=(.*?)\',(?:.*?) bold;">(.*?)</a>';

Jest to wyrażenie regułowe, w którym:
1. Najpierw szukasz tekstu "?id=" (zwróć uwagę, że znak "?" trzeba poprzedzić znakiem "\").
2. Dalej -wzorzec przechwytujący nr 1 - "(.*?)"
Dodałem tu "?" aby wyszukiwanie było w wersji "skąpej" (ungreedy).
3. Potem (za szukanym tekstem nr 1) ma być apostrof i przecinek.
4. Kolejny fragment - (?:.*?) - to subwzorzec nieprzechwytujący (?:).
"skonsumuje" tekst przed tym co dalej, ale nie zwróci do wyniku.
5. Dalej mamy tekst poprzedzający 2-gi tekst do przechwycenia - ' bold;">'.
6. Wzorzec przechwytujący nr 2 - "(.*?)" (też w wersji "ungreedy").
7. Kończymy tekstem, który ma wystąpić po nim - "</a>".

To co powyżej przechwytuje 2 pierwsze subwzorce.
Dokończ tę konstrukcję i wstaw jako 1-szy argument do preg_match_all.

Ten post edytował Valdi_B 6.03.2011, 11:22:56
Go to the top of the page
+Quote Post
Ulysess
post
Post #7





Grupa: Zarejestrowani
Postów: 695
Pomógł: 65
Dołączył: 27.07.2009
Skąd: Y

Ostrzeżenie: (0%)
-----


to co napisałeś jest dla mnie makabrą i nic z tego nie rozumiem..
probowałem z "\" przed ? niestety nie działa - dalej zwraca tablice z wartościa 1-9... próbowałem jeszcze inaczej wstawiając w miejsce kodu JS po prostu (.*) też zwraca tablice taką jak wcześniej tylko większą o +1 . czy aby problem nie jest w czym innym (IMG:style_emoticons/default/questionmark.gif) ..
Go to the top of the page
+Quote Post
Valdi_B
post
Post #8





Grupa: Zarejestrowani
Postów: 107
Pomógł: 30
Dołączył: 19.02.2011
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Sprawdź to co radziłem:
Zamiast Twojego wywołania preg_match_all(...) zrób:

$wyr = '\?id=(.*?)\',(?:.*?) bold;">(.*?)</a>';
preg_match_all($wyr, $page, $matches);

print_r(...) powinno wydrukować pierwsze 2 subwzorce
- po '?id=',
- po 'bold;">'

A idea tego rozwiązania jest taka:

Masz tekst typu:
aaaaaaaa xxx yyy zzz aaaaaaaaaaaaaaaaa
W tekście tym:
1. Chcesz przechwycić (nieznany Ci) tekst "yyy".
2. Przed nim występuje tekst (znany) "xxx ".
3. Po nim występuje tekst (też znany) " zzz".

Wyrażenie regułowe do preg_match musi mieć postać:
xxx (.*?) yyy

Jeżeli po tym fragmencie jest inny podobny fragment do przechwycenia, to we wzorcu musisz umieścić kolejny subwzorzec nieprzechwytujący - (?:.*?).
"Skonsumuje" on tekst przed następnym "znanym" tekstem.
Ciąg dalszy wzorca to powtórzenie tego co poprzednio:
uuu (.*?) vvv
(tym razem - jakieś inne teksty przed i po tym, co chcesz przechwycić).

A tak w ogóle: poczytaj sobie o wyrażeniach regułowych:
http://pl.php.net/manual/pl/reference.pcre...tern.syntax.php
Może wtedy mój opis nie będzie taki "makabryczny".
Po prostu używam pojęć tam zawartych (powinieneś je poznać).

Ten post edytował Valdi_B 6.03.2011, 13:40:49
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 23.08.2025 - 17:40