Klávesové zkratky na tomto webu - rozšířené Na obsah stránky

Translate to English… Ins Deutsche übersetzen…

Špeky a párky v nahrazování řetězců

Jak se nenechat vypéct při nahrazování výskytů jednoho řetězce jiným.

Základní funkcí pro nahrazování řetězců v PHP je str_replace:

$s = "Lorem ipsum";
echo str_replace('ore', 'ide', $s); // vrací "Lidem ipsum"

Díky chytře vymyšlenému kódování UTF-8 ji lze spolehlivě používat i pro takto kódované řetězce. Navíc jako první dva argumenty lze uvést pole a funkce potom provede vícenásobné nahrazení. A tady narážíme na první špíček, který je třeba mít na zřeteli. Každé nahrazení prochází řetězec znovu, pokud bychom tedy chtěli ve větě pánské dárky prohodit < ⇒ a získat tak dánské párky (švédská delikatesa!), žádné pořadí argumentů k cíli nepovede:

// vrací "dánské dárky"
echo str_replace(array('dá', 'pá'), array('pá', 'dá'), "pánské dárky");

// vrací "pánské párky"
echo str_replace(array('pá', 'dá'), array('dá', 'pá'), "pánské dárky");

Hledanou funkcí, která řetězec projde jen jednou a zamezí vzniku kolizí, je strtr:

// vrací "dánské párky", hurá
echo strtr("pánské dárky", array('pá' => 'dá', 'dá' => 'pá'));

Pokud bychom hledali výskyty podle složitějších pravidel, využijeme regulární výrazy a funkci preg_replace. Ta také umožňuje vícenásobné nahrazování a chová se stejně jako str_replace. Teď však mířím jinam. Potřebuji v řetězci nahradit všechny čísla slovem hafo, což je snadné:

$s = "Radek tvrdí, že má IQ 151. Pěkný sběratelský kousek!";
echo preg_replace('#\d+#', 'hafo', $s);

Zobecněme kód, nechť umí čísla nahradit čímkoliv, co mu předáme v proměnné $replacement. Řada programátorů použije:

return preg_replace('#\d+#', $replacement, $s); // spatne!

Což bohužel není dobře. Je třeba si uvědomit, že i v nahrazovaném řetězci mají určité znaky speciální význam (konkrétně lomítko a dolar), proto ho musíme escapovat. Správné obecné řešení je:

return preg_replace('#\d+#', addcslashes($replacement, '$\\'), $s); // ok

Napadají vás ještě nějaké nahrazovací špeky?

napsáno 30. 11. 2011 | shlédnuto 2520x | nahoru


Komentáře RSS 2.0 komentářů » přidat

avatar

#1 BoneFlute nový

Nebyl by vhodnější preg_quote() namísto addcslashes() ? Nebo i v tom je nějaký špek?

Posláno 2. 12. 2011 ve 3.16 | Odpovědět
Na komentář reagoval [3] David Grudl

#2 Jakub Vrána http://php.vrana.cz/ nový

Viz též 5 let starý článek u mě :-).

Posláno 2. 12. 2011 v 6.42 | Odpovědět
avatar

#3 David Grudl http://davidgrudl.com nový

#1 BoneFlute: preg_quote použít nelze, escapuje totiž celou řadu dalších znaků kromě těch dvou požadovaných.

Posláno 2. 12. 2011 ve 21.29 | Odpovědět
Na komentář reagoval [4] BoneFlute
avatar

#4 BoneFlute nový

#3 David Grudl: Ech, já už to vidím. preg_quote() by se použilo na výraz, který se použije jako regulár, zatímco ty mluvíš o obsahu. Moje chyba.

Posláno 4. 12. 2011 ve 12.25 | Odpovědět

Tento článek byl uzavřen. Už není možné k němu přidávat komentáře.

Výtah na začátek článku na první komentář

Názory čtenářů v diskusích nejsou názory provozovatele webu, a ten za jejich obsah neodpovídá.

phpFashion © 2004, 2012 David Grudlo webu

Pokud není uvedeno jinak, podléhá obsah těchto stránek licenci Creative Commons BY-NC-ND Creative Commons License BY-NC-ND

Ukázky zdrojových kódů smíte používat s uvedením autora a URL tohoto webu bez dalších omezení.