Autor | Zpráva | ||
---|---|---|---|
zasereg Profil * |
#1 · Zasláno: 15. 2. 2011, 15:12:35
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 |
#2 · Zasláno: 15. 2. 2011, 15:54:53 · Upravil/a: Joker
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 |
#3 · Zasláno: 15. 2. 2011, 15:59:08 · Upravil/a: TomášK
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 |
#4 · Zasláno: 15. 2. 2011, 16:10:24
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 * |
#5 · Zasláno: 15. 2. 2011, 16:17:50
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 |
#6 · Zasláno: 15. 2. 2011, 16:25:40 · Upravil/a: imploder
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 * |
#7 · Zasláno: 15. 2. 2011, 17:59:53
supr, díky
|
||
Časová prodleva: 13 let
|
0