Starší komentáře ke článku: Perl-compatible regulární výrazy v PHP - subvýrazy a zpětná reference

Zpět na článek | Úvodní stránka Interval.cz

Avatar

Autor komentáře: Radek Hulán

Datum vložení: 18.2.2005 9:36:06

Perfektní článek, stejně jako ten předchozí díky :-) Btw, nezapomnělo se na preg_replace_callback() nebo bude v dalším díle?

Avatar

Autor komentáře: Miroslav Pecka

Datum vložení: 18.2.2005 19:45:09

nezapomnělo:-) preg_replace_callback() a i další funkce budou v popsány (s příslušným příkladem samozřejmě) později

Avatar

Autor komentáře: Žnec

Datum vložení: 18.2.2005 11:42:11

Trochu nechápu použití (>| [^>]*>), když stačí ([^>]*>). Má to nějaký význam, který jsem nepochopil?

Avatar

Autor komentáře: martinm

Datum vložení: 18.2.2005 12:47:50

a na co je <*)>< ?

Avatar

Autor komentáře: mirun

Datum vložení: 23.2.2005 21:50:49

...třeba k jídlu? teda, pokud to není <*)))><, tam by se při setkání mohly role vyměnit...

Avatar

Autor komentáře: David Zámek

Datum vložení: 18.2.2005 15:36:38

Myslím, že vámi uváděný výraz nestačí - jde o to, že přímo za názvem tagu může být buď uzavírajíci značka ">", nebo mezera.

Avatar

Autor komentáře: Žnec

Datum vložení: 18.2.2005 17:43:00

Mezeře přeci vyhoví [^>]* a když tam nebude, tak taky, protože hvězdička znamená libovolný počet výskytů, takže i žádný výskyt.

Avatar

Autor komentáře: David Zámek

Datum vložení: 18.2.2005 18:21:08

Mezeře samozřejmě že jí vyhoví, ale jde o to, že mimo ">" a mezeru tam nesmí být nic jiného - takhle vyhoví i <prexxx>, které vyhovět nemá - v konkrétním případě to možná nevadí, protože se nebudou vyskytovat jména tagů začínajících na "pre", ale obecně to zadání (nahradit pouze tagy <pre>) neodpovídá.

Avatar

Autor komentáře: Miroslav Pecka

Datum vložení: 18.2.2005 19:39:56

Pro konkrétní tagy uvedené v příkladu by stačilo i Vaše řešení, pro libovolné tagy však ne. Mohu totiž také chtít hledat tag P a mám-li v kodu taky PRE, pak by Vaše řešení "matchovalo" i to P z PRE. <(\/?)p([^>]*>) matchuje <pre> <(\/?)p(>| [^>]*>) nematchuje <pre>

Avatar

Autor komentáře: Leo

Datum vložení: 18.2.2005 23:22:59

Neodpustim si to - spravne cesky i slovensky je to "mecuje", a proto je regularnimu vyrazu taky casto rika meciar :-) Leo

Avatar

Autor komentáře: Juro

Datum vložení: 19.2.2005 10:41:33

Preco urazas regularne vyrazy :-))

Avatar

Autor komentáře: Fanda

Datum vložení: 19.2.2005 0:29:39

Pekny clanek .. s preg si hraju uz naky ten patek. Posledni dobou sem se snazil napsat (obliebene) [b]nahrazovani URL odkazu v textu[/b] za ANCHORs. S dostupnymi priklady (i vlastnim resenim) mam porad jeden problem. [b]Specifikace je:[/b] nahrad vse co zacina na http:// nebo na www; dal obsahuje libovolne znaky (spec z RFC) ale ne mezeru. Cely retezec tedy konci na mezere (new line, tab, apod..). Ale to nejtezsi pro mne je, ze URL smi obsahovat carku, ale je-li carka posledni znak, pak ji nezahrn. Takze potrebuji aby tato url se nahradila cela: [b]www.neco.cz/a=1,26&b=2,66[/b] kdezto v teto URL nahrad www.seznam.cz ale ne carku: [b]..a dale se kouknete na www.seznam.cz, kde najdete ... bla bla bla[/b] nahrazeni pak prijde do klasickych ANCHORs Poradite? (ps, koukam ze zde, na INTERVALU mate podobnou vec rovnez implementovanou, ale ani Vy ji nemate (pro me ucely) dostatecne doresenou

Avatar

Autor komentáře: Vilém Málek

Datum vložení: 19.2.2005 0:35:58

Mno, já to ještě pořeším, žádný strach. Ono je o dost těžší pracovat s reguláry v jazyce, který má tak mizivou podporu výrazů jako ASP ;-)

Avatar

Autor komentáře: Fanda

Datum vložení: 19.2.2005 0:58:02

To ja vim ;-) Taky obcas kouknu jak se co (ne)da udelat v ASP. ALe me hlavne zajima, jak mam vyse popsane udelat v PHP ;-)) Nemate tuseni?

Avatar

Autor komentáře: Vilém Málek

Datum vložení: 20.2.2005 3:29:25

Mimochodem, kdybyste se nesnažil to svoje "www.neco.cz/a=1,26&b=2,66" ztučnit (nebo jinak vyznačit), bylo by se to správně převedlo na odkaz - algoritmus rozpoznávání odkazu v textu totiž hledá řetězec začínající "http://", "www" nebo "ftp" za mezerou... Pokud byste na ztučnění trval, musel byste udělat za značkou pro začátek tučného písma a před značkou pro konec tučného písma mezeru - jinak řečeno [b] www.neco.cz/a=1,26&b=2,66 [/b] se zobrazí jako [b] www.neco.cz/a=1,26&b=2,66 [/b]. (A můžete hádat, jak jsem tohle vykouzlil ;-)

Avatar

Autor komentáře: honza

Datum vložení: 19.2.2005 12:29:41

Mam takovej dotaz - funkci eregi() jsem si zkontroloval zda string obsahuje neco podle regularniho vyrazu a ulozim to do pole podle () ve vyrazu.. konkretne me zajima druha zavorka \\2 a to mam ulozeny v $pole[2]. Pak chci v tyhle casti nahradit treba mezery za &nbsp; apod. udelam si to s polem[2] a eregi_replace() nahradim puvodni string podle reg. vyrazu.. funguje to dobre, ale pokud mam ve stringu dve a vic takovych sekci ktery vyhovujou pravidlu v reg. vyrazu, nahrazeni fci eregi_replace() s hodnotou pole[2] se provede na vsechny ostatni vyskyty.. :( Pokud bych to pole[2] neupravoval a v reg. vyrazu dal \\2 tak to funguje dobre, ale takhle mam vsude obsah pole[2] coz je blbe... Nevite jestli se da nejak udelat aby eregi_replace() nahrazovala jen 1. nalez reg. vyrazu a ne vsechny? Popripade jak to udelat abych mohl pokazde zmenit hodnoty v \\2? Asi je to ponekud neprehledny, dystak to popisu jeste jednou. Diky ;)

Avatar

Autor komentáře: acidofil

Datum vložení: 19.2.2005 22:13:01

caj, sice absolutne nechapu tvuj zmatene popsanej problem a radsi ho ani chapat nechci, ale na na regexpy pouzivej preg_*, ereg je pomalejsi a vubec je to takova prasarna trochu imho. Mno a u preg_replace mas pak jako posledni argument funkce limit.. viz manual... mixed preg_replace ( mixed pattern, mixed replacement, mixed subject [, int limit]) majse

Avatar

Autor komentáře: honza

Datum vložení: 19.2.2005 23:06:49

Diky, chapat to nemusis, preg_replace se skvelym parametrem limit jsem prehlid a ted uz to zvladnu.. ;-) jeste jednou dik.

Avatar

Autor komentáře: dgx

Datum vložení: 20.2.2005 16:00:27

Nedá mi to, musím upozornit čtenáře (i autora?) článku na závažný nedostatek. Zpětné reference se [b]neodkazují[/b] pomocí \\1 \\2 atd, ale pomocí \1 \2 atd. Naopak, použití dvojitého lomítka nebude fungovat dle očekávání a namísto reference se vypíše řetězec \1 Při zápisu řetězců v PHP (ať už pomocí jednoduchých nebo dvojitých uvozovek) je třeba respektovat jejich pravidla: http://www.php.net/manual/en/language.types.string.php Zde najdete také informaci o tom, že sekvence dvou po sobě jdoucích \\ se interpretuje jako jedno \ - odsud také důvod, proč v uvedených příkladech skutečně dvojité lomítko funguje. Lze říci (s trochou nadsázky), že [b]příklady v článku fungují jen shodou náhod[/b]. Pokud by se regulární výrazy načítaly ze souboru nebo databáze, už by nefungovaly.

Avatar

Autor komentáře: Vilém Málek

Datum vložení: 20.2.2005 17:08:30

Promiňte, ale dovolím si vám odporovat. [b]Funkčnost regulárních výrazů, jako prakticky čehokoli, je závislá na kontextu.[/b] Regulární výrazy v článku fungují, protože jsou v daném kontextu správně zkonstruovány. Nelze paušálně tvrdit, že by nefungovaly, pokud by se načítaly z databáze - nevíte totiž, jakým způsobem by se do ní ukládaly a následně četly. Shodou okolností mám s "ukládáním a načítáním" regulárních výrazů a částí programů v PHP do databáze rozsáhlé zkušenosti a právě příklady z článku by v mé aplikaci fungovaly naprosto správně. Mimochodem, ani druhá metoda, popsaná v článku (odkaz prostřednictvím znaku "$"), není nezávislá na kontextu, takže i v jejím případě musíte možné konflikty aktivně předjímat a řešit ;-)

Avatar

Autor komentáře: dgx

Datum vložení: 20.2.2005 19:49:47

Věta "Obecně je tedy zpětná reference ve tvaru \\n, kde ..." hovoří o obecných pravdách a tím pádem je chybná. Obecně je totiž zpětná reference ve tvaru \n > Nelze paušálně tvrdit, že by nefungovaly, pokud by se načítaly z databáze To nemyslíte vážně :-) Při načítání z databáze předpokládám (vždy), že data neprocházejí žádnou transformací. Tedy dostanu takový string, jaký jsem tam poslal. Mně nejde o hledání kontextově nezávislých metod - ale závislost na kontextu je třeba explicitně zdůraznit. Zkrátka fakt, že reference se zapisují jako \1 a kontext si vynucuje zapsat zdvojené lomítko, je něco diametrálně jiného, než věta "reference se zapisují jako \\1". Tedy alespoň na serveru s úrovní jakou má Interval.cz by to mělo být samozřejmé.

Avatar

Autor komentáře: Vilém Málek

Datum vložení: 21.2.2005 1:21:35

Jestliže jsem se domníval, že vašemu předchozímu příspěvku rozumím, tento nějak nedokáži pochopit. Pokusím se tedy reagovat odhadem: 1. Příklady v článku fungují, protože jsou vytvořeny v souladu s pravidly pro tvorbu regulárů v PHP, viz http://www.php.net/manual/en/function.preg-replace.php. 2. Vkládám-li něco do databáze, musím to zpracovávat transparentně tak, aby výstup byl roven vstupu. Dodržím-li tuto podmínku, pak je irelevantní, co na vstup vkládám. Vaše poznámka o databázích v předchozím příspěvku tak ztrácí smysl. Význam by měla jedině tehdy, kdybyste se snažil regulár do databáze uložený z ní vybrat a použít v jiném kontextu, ale to přeci nechcete, když tvrdíte, že vám nejde o kontextově nezávislé metody? 3. Závislost na kontextu je v článku vyjádřena, a to dokonce v několika úrovních. Kontextem je rubrika PHP, identifikace seriálu jako perl-compatible zaměřeného, identifikace článku jako popisu subvýrazů a zpětných referencí, identifikace části článku jako praktické implementace subvýrazů a referencí v PHP a dalším nadpisem, který přímo určuje funkci, která s regulárem pracuje. Jestli vám toto nepřipadá jako dostatečně explicitní vyjádření, pak nevím, co více byste ještě chtěl - přeci nelze ke každému slovu připojovat citaci z výkladového slovníku. Abych to shrnul, domnívám se, že tentokrát zbytečně hledáte komplikace tam, kde je nikdo jiný nevidí, protože článek vnímá tak, jak je napsán, a nesnaží se číst mezi řádky.

Avatar

Autor komentáře: dgx

Datum vložení: 21.2.2005 9:26:35

Nejspíš si nerozumíme - zkusím připravit příklad a pošlu sem odkaz. Už tohle téma rozpitváváme velmi široce. Jedinou chybou článku je fakt, že zpětné reference se neodkazují pomocí \\1 \\2, ale pomocí \1 \2. Včetně kontextu, že jde o rubriku PHP a použití konkrétních funkcí - toť vše, databáze z toho vynechme.

Avatar

Autor komentáře: Milan

Datum vložení: 21.2.2005 14:09:57

Souhlasim s Vami. Ono vubec by bylo lepsi nepouzivat retezcove konstanty oharanicene uvozovkami, kde to neni zapotrebi a misto toho pouzivat apostrofy - parsovani je pak i rychlejsi - a doporucuji to i tvurci PHP. Nicmene je na zapisu vyrzu v PHP jedna divna vec. PHP jako takove zna escape sekvenci \n, jak to , ze pak funguje rewg, vyraz s "/xxx\n/"? Nebo takovy vyraz nefunguje a musi se zapsat "/xxx\\n/"? Ted nevim ... asi bych pro jistotu pouzil ty apostrofy.

Avatar

Autor komentáře: dgx

Datum vložení: 21.2.2005 15:52:08

Bude fungovat obojí. Pokaždé se ale předá jiný řetězec. Jednou bude obsahovat přímo znak pro nový řádek (#10), a jednou dva znaky \ + n. A protože obojí regexp chápe stejně, nebude to mít na funkčnost vliv. Ale tohle už neplatí například pro znak $ - pokud jej hledáme, musíme v regulárním výrazu použít "\\$" nebo '\$', protože "\$" by nefungovalo.

Avatar

Autor komentáře: dgx

Datum vložení: 22.2.2005 13:09:30

Vysvětlení toho, proč je v článku chyba + jeden příklad navíc :-) http://www.dgx.cz/trine/item/regularni-korektura-intervalu-cz

Avatar

Autor komentáře: Vilém Málek

Datum vložení: 23.2.2005 0:04:31

No tedy, kdybyste nemluvil o "chybě" a rovnou napsal do prvního komentáře, že vám jde o typ uvozovek, byl bych s vámi okamžitě souhlasil a mohli jsme si ušetřit diskusi... Také se domnívám, že regulární výrazy se mají používat s jednoduchými a ne s dvojitými uvozovkami. (Ostatně, jednoduché uvozovky by se IMHO měly používat v PHP takřka všude ;-)

Avatar

Autor komentáře: dgx

Datum vložení: 23.2.2005 6:20:35

:-) o typ uvozovek mi ani tak nejde, jako spíš o chybnou informaci v článku, že zpětné reference se zapisují pomocí \\[i]n[/i], zatímco správně má být \[i]n[/i]

Avatar

Autor komentáře: kinghowa

Datum vložení: 28.2.2005 17:58:04

Některým došlo, o co jde ... bez urážky ;-). Sice se programováním v PHP už nějaký pátek živím, ale bez zpětných referencí jsem se zatím obešel. A mě taky autor dokonale zmátl. Když se podíváte do článku, tak je tam v prvních odstavcích všude vysvícené [b]\\x[/b]. Nikde není ani zmínka o tom, že autor ošetřuje uvozovky, natož aby třeba uvedl [b]"\\x"[/b]. A protože název článku není např. [i]Jak na escape sekvence[/i], tak souhlasím s tím, že je to matoucí a je to chyba. Ok, tak chybka ... nicméně stejně dík za rozšiřování obzorů.

Avatar

Autor komentáře: Miroslav Pecka

Datum vložení: 20.2.2005 19:48:38

viz http://cz.php.net/manual/cs/function.preg-replace.php

Avatar

Autor komentáře: lp

Datum vložení: 4.3.2005 8:34:24

uz sa tesim na dalsi diel, kedy bude?

Avatar

Autor komentáře: Vlasec

Datum vložení: 7.8.2008 14:23:16

Zajímavý příklad na předvedení síly regulárních výrazů, doufám ale, že to nikdo nepoužil v praxi. Zkazilo by to věty jako tyto: "Voják si hledí hledí a hlavně hlavně", "Srazil se se stromem", "černý bez bez listí" a podobně :) Myslím, že taková úprava textu by udělala více škody než užitku, když navíc hodně lidí nepoužívá diakritiku a tím může podobných shod přibýt.

Zpět na článek | Úvodní stránka Interval.cz