Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Wyrażenie regularne, które będzie zawierało ciąg i tyle samo zamkniętych nawiasów, co otwartych
Forum PHP.pl > Forum > PHP
Sebusik
Na wstępie wybaczcie mi ten tytuł, naprawdę nie wiem jak opisać mój problem w tytule.

Generalnie chcę, aby był wyłapywany ciąg znaków, który jest zawarty w nawiasie. Problemu nie ma, gdy mam niemieszane nawiasy:
  1. Jakiś tekst ({w nawiasach}).

Wyrażenie regularne wygląda tak:
  1. #\(\{(.*?)\)\}#

Jednakże problem jest, bo te nawiasy są mieszane:
  1. Jakiś test ({jakiś inny tekst ({i tutaj jeszcze jedenk}) znowu )}.

I tutaj też w zasadzie problemu nie ma:
  1. #\(\{(.*)\}\)# //tutaj wychwytuje rozpoczęcie nawiasu "({" oraz ostatni nawias w wyrażeniu "})"

Problem następuje, kiedy nawiasy są mieszane i jest kilka "głównych":
  1. Jakiś tekst ({tutaj też ({i tutaj}) również }), tutaj następny ({nawias główny ({a w nim }) jakiś }) tekst.

Stosując takie wyrażenie:
  1. #\(\{(.*?)\)\}#

Wyciągnie on:
  1. ({tutaj też ({i tutaj})

A stosując takie:
  1. #\(\{(.*)\}\)#

Wyciągnie on:
  1. ({tutaj też ({i tutaj}) również }), tutaj następny ({nawias główny ({a w nim }) jakiś })

A mi zależy na tym, aby wyciągnąć:
  1. ({tutaj też ({i tutaj}) również })

Czyli tyle ile razy nawias został otwarty to tyle razy musi zostać zamknięty.

Ktoś ma pomysł, jak się do tego zabrać?
kamil4u
  1. $test = 'Jakiś tekst ({tutaj też ({i tutaj}) również }), tutaj następny ({nawias główny ({a w nim }) jakiś }) tekst.';
  2. preg_match_all('#\(\{([^,]*?)\)\}\#U', $test, $matches);
  3. echo('<pre>');
  4. var_dump( $matches );
  5. echo('</pre>');
cycofiasz
  1. <?php
  2.  
  3. $string = 'Jakiś tekst ({tutaj też ({i tutaj}) również }), tutaj następny ({nawias główny ({a w nim }) jakiś }) tekst.';
  4.  
  5. preg_match_all("#\(\{(?:[^({})]+|(?R))*\}\)#",$string,$matches);
  6.  
  7. echo "<pre>"; print_r($matches); echo "</pre>";
  8.  
  9. ?>
Sebusik
Super, dzięki wink.gif

Jednak mam pytanie odnośnie tego: masz może jakiś artykuł w internecie, gdzie były by wyrażenia regularne bardziej zaawansowane? Ze wszystkimi artykułami, z którymi się spotkałem (przykład) to podstawy, nie ma w nich mowy o tym, co użyłeś powyżej (np. "?:", "+|" czy "?R") wink.gif
cycofiasz
Ostatnio się natknąłem na takie coś: http://gajdaw.pl/php/wyrazenia-regularne-p...utorial/p1.html
Resztę zagadnień związanych z PCRE łatwiej odnaleźć na anglojęzycznych stronach.
Sebusik
Dzięki jeszcze raz smile.gif Jak będę miał jakiś problem to napiszę wink.gif
---

No i jednak mam problem. Wyrażenie działa poprawnie, ale gdy mam np. taki tekst:
  1. Jakiś tekst ({tutaj tekst w podwójnym nawiasie (a tutaj w nawiasie) lorem}) ipsum.

To nie wykrywa tego podwójnego nawiasu (co jest zasługą pojedynczego w środku). Da się coś z tym zrobićquestionmark.gif
Crozin
Pewnie by się dało (nie zajmowałem się odwołaniami rekurencyjnymi w wydaniu PHP-owskich wyrażeń regularnych, więc nie mam pewności), ale tutaj już powoli wkraczasz w problemy, do rozwiązywania których nie powinieneś wykorzystywać wyrażeń regularnych - nie nadają się one do tego typu zadań.

Prawdopodobnie najlepszym rozwiązaniem byłoby tutaj napisanie prostego parsera, który analizując znak po znaku byłby wstanie przekształcić to w jakąś normalną strukturę.
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.