Autor Zpráva
GeneralDv
Profil
V textu potřebuju nahradit jeden kód za něco, funkcí preg_replace_callback(), smí se nahrazovat jen to co neni escapovaný \, to co je musí zustat celý:
[tag]xxx[/tag]
\[tag]xxx[/tag]

Napsal sem regulár, se kterym si dál už nevim rady:
~[^\\\]\[tag\](.*?)\[/tag\]~sim

Vyskytly se mi tam chyby:
- když je na začátku stringu a nic před nim neni, NIKDY se neprovede
- vždy když neni na začátku stringu, se provede, i když je escapovanej ten kód

Dokážete mi někdo dál poradit?
Casper
Profil
GeneralDv:
použijte negative lookbehind assertion:
~(?!=\\\)\[tag\](.*?)\[/tag\]~sim
GeneralDv
Profil
Dík za snahu ale dělá to taky problémy - když to escapuju, vráti to jen \ ale ne celej výraz (BBkód).
Casper
Profil
GeneralDv:
Ano, omlouvám se, chyba. V php je negative lookbehind assertion ?<!, tedy
~(?<!\\\)\[tag\](.*?)\[/tag\]~sim
by mělo být to, co požadujete.
GeneralDv
Profil
Hm funguje, moc díky. Příde mi že sem dobře neschopnej protože sem se na seznam těhle konstrukcí díval a nic.
Casper
Profil
GeneralDv:
Assertions je vhodné si vrýt do paměti, každopádně by jich v tomto případě ani nebylo potřeba, jen jsou mnohem elegantnější. Taktéž by však mělo fungovat:
"~(^|[^\\\])\[tag\](.*?)\[/tag\]~sim"

ovšem zde je třeba si uvědomit, že do výsledku je započítáván i znak před BBcode tagem, takže pokud by vám šlo o odstranění tagu, musel by se onen znak doplnit pomocí zpětných referencí, nějak takto:
preg_replace("~(^|[^\\\])\[tag\](.*?)\[/tag\]~sim", "$1$2", $string);

namísto pohodlných assertions (které se do zpětných referencí nezapočítávají, proto $1), kde by to vypadalo nějak takto:
preg_replace("~(?<!\\\)\[tag\](.*?)\[/tag\]~sim", "$1", $string);

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: