Autor Zpráva
TDKcd
Profil *
Potřeboval bych vysvětlit níže uvedený skript, na ošetření "formátovacích značek" jako <B> v textu, odesílaný přes formulář do databáze. Nějak mi to hlava nebere :( ... tak nějak polopaticky, znak po znaku, co který vlastně ošetřuje. (especially tu část $vyraz[]="/[[bB]](.+?)[/[bB]]/s"; a $nahradit[]='<b>\1</b>'; ) To je pro mě PEKLO

function prekodovat_formatovani($text) {

$vyraz=array();
$nahradit=array();

$vyraz[]="/[[bB]](.+?)[/[bB]]/s";
$nahradit[]='<b>\1</b>';

$vyraz[]="/[[iI]](.+?)[/[iI]]/s";
$nahradit[]='<i>\1</i>';

$text=preg_replace($vyraz, $nahradit, $text);
return $text;
}

DÍKY DÍKY MOC
one_k
Profil
co je na tom tezkeho?

z [b(nebo)B]nejaky text[b(nebo)B]
to udela <b>nejaky text</b>
TDKcd
Profil *
Já vím co to dělá, ale proč jsou poskládané tak ty jednotlivé znaky / [ [ b B ] ] ( . + ? ) [ / [ b B ] ] / s

Co který dělá, od lomítka až po to "s"

A pak

<b>1</b> ... proč je tam to 1

Já regulární výrazy moc nechápu, tak bych potřeboval vysvětlení jak pro blbce :)
Joker
Profil
especially tu část $vyraz[]="/[[bB]](.+?)[/[bB]]/s"; a $nahradit[]='<b>1</b>';
No to je právě ten regulární výraz :-)

Předpokládám, že fórum odstranilo escapování a ten výraz měl původně vypadat:
$vyraz[]="/\[[bB]\](.+?)\[/[bB]\]/s";

Znamená to:
Znak "[", následovaný "b" nebo "B" následovaný "]", potom žádný, jeden nebo více jakýchkoliv znaků s v "líném" režimu* a potom "[/", "b" nebo "B" a "]"

Modifikátor "s" na konci znamená, že se bude hledat i přes více řádků (bez něj se hledá jen do konce řádku)

* režim může být "líný" a "nenasytný". Líný vybere nejkratší možný řetězec odpovídající výrazu, nenasytný vybere nejdelší možný.
Příklad
Toto je [b] nějaký text [/b] nějaký další text [/b]
Výsledek nahrazení v líném režimu: Toto je nějaký text nějaký další text [/b]
Výsledek v nenasytném režimu: Toto je nějaký text [/b] nějaký další text

A ještě přidám odkaz pro výklad Perl-compatible regulárních výrazů "od začátku": http://interval.cz/serialy/perl-compatible-regularni-vyrazy-v-php/
Joker
Profil
Oprava:
část: potom žádný, jeden nebo více jakýchkoliv znaků s v "líném" režimu*
má správně být: potom jeden nebo více jakýchkoliv znaků v "líném" režimu*

Upravil bych přímo ten svůj příspěvek, ale rozhodilo by mi to zpětná lomítka...
one_k
Profil
aha

tady se to blbe popisuje jelikoz toto forum na stejnou fci takze to zkusim takto:

1) - najdi [
2) - if(1) najdi vyskyt b nebo B
3) - if(2) najdi ]
4) - if(3) najdi alespon jeden vyskyt jakehokoli znaku az po [ a tyto znaky uloz (do $1 - ulozeny v pameti php parseru)
5) - if(4) najdi /
6) - if(5) najdi b nebo B
7) - to 's' znamena ze ta . odpovida i znaku noveho radku (
)

8) - if(1-7) vypis: <b>obsah $1</b>

takto zjednodusene to snad pujde pochopit.

http://www.root.cz/serialy/regularni-vyrazy/

edit: aj Joker me predbehl o 6minut :) neni nad to otevrit si thread a odpovidat az po case..
Joker
Profil
one_k
1) - najdi [
2) - if(1) najdi vyskyt b nebo B

No tak právě ne... ty znaky musejí následovat bezprostředně za sebou.

neni nad to otevrit si thread a odpovidat az po case..
Tak to velmi dobře znám :-)
TDKcd
Profil *
Jsem z toho trochu jelen, ale budu se pilně učit :o))

Díky moc

P.S.: Co je "líný" a "nenasytný" režim ?

P.S.S.: Pořád mi ale naní jasný ta druhá část ...

$nahradit[]='<b> zpětné lomítko zpětné lomítko 1</b>';

... proč je tam ta jednička a ty lomítka ?
jonge
Profil
TDKcd
Líný najde nekratší řetězec, nenasytné nejdelší řetězec odpovídající regexpu.
Ty lomítka jsou referencí na ty věci v závorce, takže to co máš v první kulaté závorce bude \\1, v druhé závorce \\2 atd.
Joker
Profil
TDKcd
Co je "líný" a "nenasytný" režim ?
Však viz ten můj příklad. Vstup je: Toto je [b] nějaký text [/b] nějaký další text [/b] další text
Regulárnímu výrazu odpovídá [b]*cokoliv*[/b] Ale takové texty jsou tam dva:
[b] nějaký text [/b] - vyhovuje regulárnímu výrazu
[b] nějaký text [/b] nějaký další text [/b] - taky vyhovuje

Přičemž ten první leží uvnitř toho druhého. Líný bere co nejkratší: jakmile narazí na první [/b], skončí. Takže vezme ten první. Nenasytný bere co nejdelší který odpovídá, takže v tomhle případě by bral všechno mezi prvním výskytem "[b]" a posledním výskytem "[/b]"
TDKcd
Profil *
a kdy se script provede "líně" a kdy "nenasytně" ?
Mastodont
Profil
Seriál na rootu
Spešl web o reg výrazech
Joker
Profil
TDKcd
a kdy se script provede "líně" a kdy "nenasytně" ?
Ne skript, ale regulární výraz.
Ve výchozím nastavení je regulární výraz nenasytný. S modifikátorem "u" je líný. Přidáním otazníku za kvantifikátor +, *, ?, {...}, tedy +?, *?, ?? a {...}? se ten konkrétní kvantifikátor chová naopak, než je nastavení regulárního výrazu.
Takže:
(.+) - nenasytný
(.+?) - líný
- Pokud by u regulárního výrazu byl použitý modifikátor "u", bude to obráceně.
Takže:
/\[[bB]\](.+?)\[/[bB]\]/s"
je totéž jako:
/\[[bB]\](.+)\[/[bB]\]/su"

Ale přijde mi zbytečné tu do detailu rozebírat konstrukci regulárních výrazů, jaký je smysl jednotlivých kvantifikátorů a modifikátorů, pro tento účel viz mnou už zmíněný seriál o perl-compatible regulárních výrazech: http://interval.cz/serialy/perl-compatible-regularni-vyrazy-v-php/
anebo seriály, které uvedli ostatní diskutující.

Na experimenty s regulárními výrazy bych ještě doporučil pěkný prográmek jménem RegEx Coach, http://weitz.de/regex-coach/ který umí zvýraznit části zadaného řetězce či řetězců, odpovídající zadanému regulárnímu výrazu. Výborné na experimenty, stačí si vhodně zvolit pár testovacích řetězců a potom různě měnit regulární výraz a sledovat, jak se ta změna projeví.
Kubista
Profil
Zdravím,
zkouším prakticky to samé co tady kolega výše, ale nějak jsem se nedopídil co doplnit místo "$promenna", aby se tam zobrazil původní řetězec. Když tam dám //1 tak se vypíše "//1".

eregi_replace("[(b)](.+)[(/b)]", "<b>$promenna</b>", "[b]fgh[/b]");

Předem děkuji za rady :-)
bukaj
Profil
Když tam dám //1 tak se vypíše "//1".
to bude tím, že to musí být zpětnými lomítky.
Kubista
Profil
Jejda, díky moc. :-)
bukaj
Profil
Kubista
není zač
Kubista
Profil
Mohl by mi ještě někdo poradit jak to udělat, aby byl tento regulární výraz líný?
eregi_replace("[(b)](.+)[(/b)]", "<b>\2</b>", "$text");


Zkoušel jsem to nějak takto, ale to je bohužel špatně :-(
eregi_replace("[(b)](.+?)[(/b)]", "<b>\2</b>", "$text");
Toto téma je uzamčeno. Odpověď nelze zaslat.