Autor Zpráva
zasereg
Profil *
Ahoj. Peru se už nějakou dobu s regulárním výrazem. Na vstupu mu předhazuji řetězec TEXT nebo {TEXT} a potřebuju aby $matches[1] odpovídal tomu TEXT.
preg_match('/^\{?(.*)\}?$/', '{TEXT}', $matches);
echo $matches[1]; // vrací TEXT}, ale měl by vracet TEXT

Jednoduše řečeno potřebuju vracet vnitřek {VNITREK} jako VNITREK, {VNIT{REK} jako VNIT{REK, {{VNITREK}} jako {VNITREK}, VNITREK jako VNITREK, dobré by bylo aby na {VNITREK nevracel nic (neplatný výraz). Snažil jsem se to řešit i takto: /^(\{(.*)\}|(.*))$/ ale tam je zase proměnná délka pole (jednou odpovídá $matches[2], jednou $matches[3]). Kde dělám chybu?
Joker
Profil
zasereg:
Na to asi regulární výraz stačit nebude, jestli to má umět i rozeznávat související závorky ({{VNITREK}}{VNITREK}), bude potřeba na to napsat parser, asi.

Edit:
Respektive, má to umět zpracovat i něco takového: {Text} něco mezi {text2} něco?
TomášK
Profil
Joker:
Naopak, řekl bych, že na to co, chce jsou i regulární výrazy zbytečný kanón. Stačí se kouknout, zda první znak řetězce je '{', pokud ano, ověřit, že poslední znak také '}' a vzít podřetězec bez krajních znaků. Pokud první znak není '}', pak vrátit celý text. Regulární výraz nefunguje, protože .* je greedy - sežere celý řetězec i s koncovou závorkou. Jde to nastavit nějakým modifikátorem.

Edit: psáno před zhlédnutím editu :)
Joker
Profil
TomášK:
Přesně.
Čili buď to je takhle jednoduché, nebo naopak tak složité, jak píšu já :-)

Ještě také záleží, jestli například {{TEXT} má dát výsledek {TEXT, nebo to je neplatný vstup.
zasereg
Profil *
Joker:
Ještě také záleží, jestli například {{TEXT} má dát výsledek {TEXT, nebo to je neplatný vstup.
Ano takový výsledek má dát, naopak pokud přijde na vstup {TEXT tak je to neplatný vstup. Prostě buď bude vracet všechno mezi první a poslední {} nebo bude vracet všechno (kromě případu kdy se jako první znak vyskytuje {, ale poslední není } a naopak). Osobně si myslím, že to lze řešit konstrukcí (první případ|druhý případ), ale tato konstrukce vrací ten TEXT někdy v $matches[2], někdy v $matches[3]. Nejde to nějak ovlivnit nebo to musím explicitně testovat jinak?
imploder
Profil
zasereg:
Je to proto, že hvězdička (*) má jako výchozí chování tzv. hladové vyhodnocování. To znamená, že podvýraz ".*" sežere nejvíc znaků, co může; postupuje se zleva doprava, takže ukončovací závorka ("}") byla taky sežrána podvýrazem ".*". Pro tvoje použití je potřeba přepnout na líné vyhodnocování, to znamená že ".*" sežere naopak nejmíň znaků, co může; tedy před "}" se zastaví. Na líné vyhodnocování se operátory přepínají napsáním "?" za operátor. Přidáme tedy za hvězdičku otazník:
preg_match('/^\{?(.*?)\}?$/', '{TEXT}', $matches);

To funguje jak má.
zasereg
Profil *
supr, díky

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: