Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP]Wyrażenia regularne - złapanie między przecinkami z małym wyjątkiem
Forum PHP.pl > Forum > Przedszkole
konrados
Hej.

Powiedzmy, że mamy taki string:

  1. $string='
  2. blah<br>
  3. @include (\'file_to_load\')
  4. <br>
  5. @include (\'file_to_load\',\'param1\',\'param2\',\'param3\')
  6. ';


Chcę złapać (i ewentualnie zastąpić funkcją preg_replace_callback) wszystkie wystąpienia @include wraz z ich parametrami, robię więc:

  1.  
  2.  
  3. $string='
  4. blah<br>
  5. @include (\'file_to_load\')
  6. <br>
  7. @include (\'file_to_load\',\'param1\',\'param2\')
  8. ';
  9. $params=[];
  10. '~@include \((,?.*?)\)~',//łapię @include, nawiasy i wszystko między nimi
  11. function ($matches) {
  12. echo '---iteration---';
  13. $params=explode(',',$matches[1]);//rozdzielam parametry wg przecinka
  14. echo '<pre>';
  15. var_dump($params);
  16. echo '</pre>';
  17. return $matches[1];
  18. },
  19. $string
  20. );


No i działa OK, tzn. łapię to @include wraz z parametrami

Problem pojawia się, gdy w $stringu źródłowym, w samym parametrze pojawi się przecinek. Np:
  1. $string='
  2. blah<br>
  3. @include (\'file_to_load\')
  4. <br>
  5. @include (\'file_to_load\',\'param1,coś tam\',['elem'=>'też, przecinek']])
  6. ';


Tutaj w okolicach "param1" oraz czegoś co ma być arrayem są przecinki, chciałbym by były one elementem tego parametru, niestety oczywiście po użyciu funkcji "explode" ona widzi te przecinki i powstają bzdury.

Co mam zrobić, by przecinki będące w apostrofach były brane dosłownie, a nie były rozdzielnikiem parametrów?
kreatiff
Trzeba zamiast explode użyć coś bardziej skomplikowanego. Można iść ponownie w wyrażenia regularne, np.:
  1. $a = '\'file_to_load\',\'param1,coś tam\',[\'elem\'=>\'też, przecinek\'],\'as\'';
  2. $b = preg_split('#(?<=(?:\'|\])),#', $a);
  3. echo'<pre>',var_dump($b),'</pre>';
Ale trzeba to posprawdzać na wszystkich mozliwych kombinacjach występujących przy @include.
konrados
Dzięki, działa!

Nic a nic nie rozumiem z tego wyrażenia smile.gif

Muszę mocno wreszcie się za edukację w tym zakresie wziąć.

Jeśli to nie będzie skomplikowane, to jeszcze jedna drobnostka smile.gif Mając taki string:

  1. $a = '\'file_to_load\',\'param1,coś tam\',[\'elem\'=>\'też, przecinek\'],\'as\'';


To wyrażenie rozdziela też to co znajduje się pomiędzy nawiasami kwadratowymi [ oraz ] - a dałoby się by nie rozdzielało? Czyli by też zostawiło tak jak jest?

Myślałem, że po tym jak teraz poznałem funkcję preg_split to może dam radę sam, ale tak jak powiedziałem, to wyrażenie to dla mnie czarna magia...
kreatiff
Ja otrzymuję taki wynik po zastosowaniu wyrażenia, które zaproponowałem:
  1. array(4) {
  2. [0]=>
  3. string(14) "'file_to_load'"
  4. [1]=>
  5. string(17) "'param1,coś tam'"
  6. [2]=>
  7. string(27) "['elem'=>'też, przecinek']"
  8. [3]=>
  9. string(4) "'as'"
  10. }:
Czyli to co w indeksie nr 2 ma być inne? Wyjaśnij i zobaczymy co da się zrobić.

Co do wyrażenia regularnego, to szuka ono przecinka, który jest poprzedzony albo apostrofem, albo zamknięciem nawiasu kwadratowego. I string jest cięty tylko w miejscach przecinków spełniających to założenie.

?<= - positive lookbehind, po tych symbolach wypisujemy znaki, które muszą poprzedzać dopasowany znak (ciąg)
(?: ... ) - nie łap tej grupy do wyniku, w sumie to jest zbędne, preg_split niczego "nie łapie", zapędziłem się, bo bardzo rzadko z tej funkcji korzystam, przeciwnie do preg_match, gdzie to z kolei już jest często stosowane (poniżej dałem uproszczone wyrażenie))
\'|\] - znaki, które muszą poprzedzać nasz przecinek, by ten był uwzględniony jako miejsce cięcia ciągu
, - szukaj przecinka (poprzedzonego tym co wyżej wyznaczone)

Wyrzucając to co zbędne, mamy takie wyrażenie:
  1. $b = preg_split('#(?<=\'|\]),#', $a);
konrados
Wow, dzięki za wyrażenie i wytłumaczenie!
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.