Autor Zpráva
Chamurappi
Profil
Kolega _es pravil:
> Problém asi nastáva prakticky len vtedy, ak sa formátovacie značky vyskytnú v kóde a neboli prispievajúcim myslené ako BB značky.
> Hlavne značka [i].
> Ak sa za takýmto kódom použije citácia alebo iná kurzíva, nastáva problém, prvé [i] v kóde je "zožrané" a farbenie kódu je zmršené.
> Navrhoval som jednoduchú opravu, ktorá by toto jednoducho vyriešila, no bez odozvy.
> Že by sa namiesto prvej rovnakej otváracej značky brala do úvahy posledná.

Přestože nastíněný problém nepovažuji za důležitý, přemýšlel jsem nad řešením. Postupně jsem poskládal regulární výraz, který mi v JavaScriptu běhá spolehlivě (alespoň zdánlivě) a zkusil jsem ho nahrát do sandboxového bb_codes.php:
//  $pattern[4] = "/\[[iI]\](.+?)\[\/[iI]\]/s";  // původní verze
    $pattern[4] = "/\[[iI]\]([^\[]+(\[([^\[iI][^\[]*|[iI][^\[\]][^\[]*)*)*|\[)\[\/[iI]\]/s";
    $replacement[4] = '<i>\\1</i>';
    // …
    $msg = preg_replace($pattern, $replacement, $msg);
Jenže tam netrefí nic. Kde dělá PHP chybu? :-)
_es
Profil
V regulárnych výrazoch sa veľmi nevyznám, no nedá sa zotaviť niečo takéto:
Reťazec začínajúci na [i]
obsahujúci hocijakú postupnosť znakov neobsahujúcu [i]
a končiaci sa na [/i]
Alphard
Profil
Chamurappi:
Jenže tam netrefí nic. Kde dělá PHP chybu? :-)
Nevím, kde je problém.

Kód
<?php
$msg = "[i]text1[i]text2[/i]";

//$pattern[4] = "/\[[iI]\](.+?)\[\/[iI]\]/s";
$pattern[4] = "/\[[iI]\]([^\[]+(\[([^\[iI][^\[]*|[iI][^\[\]][^\[]*)*)*|\[)\[\/[iI]\]/s";
$replacement[4] = '<i>\\1</i>';

$msg = preg_replace($pattern, $replacement, $msg);
echo $msg;


mi vypisuje
[i]text1<i>text2</i>

To je očekávané chování, nebo ne?

Aha, neotestoval jsem víc řetězců, už to vidím.
AM_
Profil
Chamurappi:
občas se setkám s problémy se zpětnými lomítky v regulárech. Zkus:
- dát výraz do apostrofů místo uvozovek (nevyhodnocuje to tolik escape sekvencí)
- všechny \ změnit na \\ (i v apostrofech je imho dobré lomítka zdvojovat, sice tam mají méně sekvencí, ale i tak jich tam pár je - zrovna dneska jsem potřeboval regulárem pro analýzu cesty souboru vyjádřit lomítko jako znak a i mezi apostrofy jsem ho musel napsat 4x za sebou :) )

Možná to nepomůže, nevím, ale přinejmenším z mé zkušenosti reguláry zapsané v uvozovkách místo apostrofů vedou do escapovacích pekel.
Chamurappi
Profil
Reaguji na Alpharda:
To je očekávané chování, nebo ne?
Ano, je.

Hm, teď už mi to také funguje. Možná jsem měl omylem zaškrtnuté „Zakázat formátování“. Tak ne.
Když už je téma nastolené, nenapadá tě snazší způsob, jak toho (jen v rámci regulárních výrazů) dosáhnout?


Reaguji na _es:
Nasadil jsem to do sandboxu, důkladně to prosím otestuj, šťourale :-)
Názorně vidíš, proč zůstal tvůj návrh tenkrát bez odezvy.


Reaguji na AM:
dát výraz do apostrofů místo uvozovek (nevyhodnocuje to tolik escape sekvencí)
Zkusil jsem, nepomohlo.

všechny \ změnit na \\
Nezkusil jsem. Kdyby byl s tímhle problém, nefungovala by ani ta předchozí jednoduchá verze (v mém kódu zakomentovaná), ne?
Alphard
Profil
Chamurappi:
Hm, teď už mi to také funguje.
Jsi si jistý? Teď jsem to testoval a jsou v tom anomálie :-)

Když už je téma nastolené, nenapadá tě snazší způsob, jak toho dosáhnout?
Odpovím zítra, já tady nejsem 25 hodin denně.
Chamurappi
Profil
Zkusil jsem použít ten svůj půvabný regulární výraz v JavaScriptu na delší víceřádkový text, u kterého PHP neuspělo, a zatím nevím, jak to dopadlo (louská to teprve hodinu a půl). Už tuším, co to je Catastrophic Backtracking. Pustil jsem se proto do výzkumu „lookaroundů“ a zdá se, že záporné tvrzení o následujícím šlape:
    $pattern[4] = "/\[[iI]\](((?!\[[iI]\]).)+?)\[\/[iI]\]/s";
(Jsem si v tom ovšem hodně nejistý.)


Reaguji na _es:
Nasadil jsem to do sandboxu, důkladně to prosím otestuj, šťourale :-)
_es
Profil
Chamurappi:
Vyzerá to, že to funguje podľa očakávania.
Ešte by to mohlo byť urobené aj pre [b], aj keď nie je zvykom veľmi používať premennú b alebo B v kóde, no mohlo by sa to vyskytnúť.
Niektoré tvoje JS funkcie tuším predpokladajú pôvodné správanie - vkladanie kurzívy cez tlačítko aj cez CTRL+I, tak by to mohlo byť tiež upravené, ak by táto zmena mala zostať.
Chamurappi
Profil
Reaguji na _es:
Ešte by to mohlo byť urobené aj pre [b]
Hotovo.

Niektoré tvoje JS funkcie tuším predpokladajú pôvodné správanie
Myslím, že ani ne. Činí určitá rozhodnutí na základě kontextu, která sice můžou mít nyní jiný dopad, ale pořád je to stejně provozuschopné.
_es
Profil
Chamurappi:
Myslím, že ani ne.

Myslel som napríklad túto situáciu:
V kóde sa nachádza [i] a v nejakom ďalšom, dodatočne vysvetľujúcom texte, sa prispievajúci rozhodne označiť nejaký text kurzívou.
Teda označí text a stlačí tlačidlo na vloženie kurzívy. No namiesto toho, aby sa okolo toho označeného textu vytvorili otváracia a uzatváracia značka, tak sa vytvorí len uzatváracia značka a vo výsledku nastane podobný efekt ako pred tou zmenou.
Alphard
Profil
Alphard:
Odpovím zítra, já tady nejsem 25 hodin denně.
Rád bych býval pomohl více, ale dnes dopoledne tady již byl od Chamurappiho nový regulár, který správně zpracoval všechny mé testovací řetězce (včetně těch, se kterými měl ten původní problémy).
Jediné další zjednodušení, které mě napadá, je přidání parametru i (CASELESS), což umožní odmazat několik [ a ].
$pattern[4] = "~\[i\](((?!\[i\]).)+?)\[\/i\]~si";
Chamurappi
Profil
Reaguji na _es:
To je zase taková prkotina…
Ale opravil jsem ji.


Reaguji na Alpharda:
Rád bych býval pomohl více, ale dnes dopoledne tady již byl od Chamurappiho nový regulár
Omlouvám se, že jsem byl tak hrrr :-)

další zjednodušení, které mě napadá, je přidání parametru i (CASELESS)
Vím o této možnosti. Použil jsem obdobnou formu zápisu, kterou užívají okolní regulární výrazy.
Je /[iI]/ pomalejší než /i/i?
Alphard
Profil
Chamurappi:
Je /[iI]/ pomalejší než /i/i?
Srovnatelné, teď jsem to zkušel:
9.8316471576691
9.7984440326691
Záměrně nepíši, který je který, protože se to s každým reloadem mění, ale při 100000 nahrazení je to zanedbatelné (údaje jsou v sekundách).

Připadá mi to spíše přehlednější, ale je pravda, že konzistence s ostatními reguláry také není k zahození. Já se většinou snažím zbytečně nezávorkovat a nelomítkovat, proto taky ~ místo lomítek.

Vaše odpověď

Mohlo by se hodit

Odkud se sem odkazuje


Prosím používejte diakritiku a interpunkci.

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

0