preg_replace

Webdesign, HTML, CSS, Flash, PHP, ASP, .NET, JavaScript. Kritika www stránek na Smetišti.

Moderátor: Moderátoři Živě.cz

Odeslat příspěvekod Zbynas 24. 8. 2021 15:34

Ahoj, skoro vůbec nerozumím preg_replacu, mohl by mi prosím někdo poradit?

Potřebuji nahradit všechny \n (řádky) mezi [(.*?)] (tedy BB codem) a textem, kromě určitých tagů, jako je [url], a to ať ve formě [url][/url] nebo [url=...]...[/url].

Příklad
Kód: Vybrat vše
[h1]Nadpis[/h1]
nějaký text

Aby to ten nový řádek dalo do pryč, ale ne všechny řádky. Jen ty, které jsou zakončeny BB codem. Výsledek by měl být:
Kód: Vybrat vše
[h1]Nadpis[/h1]nějaký text


Pokud je ale ten řádek zakončen [/url], tak ovšem ne.

Cílem je docílit toho, že v celém textu odstraním odřádkování a ponechám ho jen tam, kde má opravdu být.

Ideálním řešením by bylo nahradit dvojité odřákování tak, aby se to dalo do odstavců <p></p>. Ovšem nevím jak na to, když budu mít třeba:

Kód: Vybrat vše
[h1]Nadpis[/h1]
text

text

Za H1 nemá být <br>, tudíž se musí \n odstranit.
Zbylý text hodit do odstavců. Je třeba předpokládat, že v textu budou dále nadpisy nižší úrovně.

Dokáže to někdo? ... Já zkouším už několik dní a pořád to má nějaké vady.

Kód: Vybrat vše
$text = preg_replace("/\[(.*?)\](\s+)\\n(\s+)\[(.*?)\]/s", ' [$1] [$4] ', $text);
$text = preg_replace("/\[(.*?)\](\s+)\\n(\s+)\[(.*?)\]/s", ' [$1] [$4] ', $text);
$text = preg_replace("/\[(.*?)\](\s+)\\n(\s+)\[(.*?)\]/s", ' [$1] [$4] ', $text);
$text = preg_replace("/\[(.*?)\](\s+)\[(.*?)\]/s", ' [$1] [$3] ', $text);
$text = preg_replace("/\[(.*?)\](\s+)\[(.*?)\]/s", ' [$1] [$3] ', $text);
$text = preg_replace("/\[(.*?)\](\s+)\[(.*?)\]/s", ' [$1] [$3] ', $text);
           
$text = preg_replace("/\[\/(.*?)\](\s+)\\n/", '[/$1]', $text);

$text = preg_replace("/\[h1\](.*?)\[\/h1\]/s", ' <h1>$1</h1> ', $text);
$text = preg_replace("/\[h2\](.*?)\[\/h2\]/s", ' <h2>$1</h2> ', $text);
$text = preg_replace("/\[h3\](.*?)\[\/h3\]/s", ' <h3>$1</h3> ', $text);
$text = preg_replace("/\[p\](.*?)\[\/p\]/s", ' <p>$1</p> ', $text);
$text = preg_replace("/\[b\](.*?)\[\/b\]/s", ' <strong>$1</strong> ', $text);
$text = str_replace("[br]", "<br>", $text);

$text = preg_replace("/\[table\](.*?)\[\/table\]/s", ' <table>$1</table> ', $text);
$text = preg_replace("/\[tr\](.*?)\[\/tr\]/s", ' <tr>$1</tr> ', $text);
$text = preg_replace("/\[td\](.*?)\[\/td\]/s", ' <td>$1</td> ', $text);
           
           

$text = preg_replace("/(<br>\s*)+(\n)*+(<br>)/s", ' <$4> ', $text);
           
$text = preg_replace("/\[url=(\W?)(.*?)(\W?)\](.*?)\[\/url\]/s", ' <a href="$2" target="_blank">$4</a> ', $text);
$text = preg_replace("/\\n/s", ' <br>
                                 ', $text);
return $text;


Prvních pár řádků se opakuje, protože ne vždy se to dokončí celé ... Chtělo by to nějaký repeater ...
NVidia GTX 1060 6GB, Intel Core i7-2600K @ 3,4 GHz, 16 GB DDR 3
Download 100 Mbps, Upload 100 Mbps, ping 8
VINOTÉKA U FREJKA
FREJK.CZ, FREJK.SK, FREJK.COM
Zbynas
Junior
Uživatelský avatar

Odeslat příspěvekod Just_jo 25. 8. 2021 08:06

Tady je jeden slušný nástroj pro test online
https://www.phpliveregex.com/#tab-preg-replace

Každopádně teorie by měla být taková, že se označí začátek a konec hledané fráze k nahrazení. Takže bys měl začínat znakem "]" a končit "[" a v tomto výběru hledat znaky k nahrazení.

Taky doporučuji prostudovat manuál
https://www.php.net/manual/en/function.preg-replace.php
Just_jo
Junior
Uživatelský avatar

Odeslat příspěvekod Zbynas 25. 8. 2021 10:39

Super nápad, jdu to zkoušet, diky moc :)

PS.. jak udělám, že budu chtít nahradit [*]...[ kromě [url*]...[ . Díky :)

Kód: Vybrat vše
$text = preg_replace("/\[(.*?)\](.*?)\[/s", ' $2 ', $text);


A hlavně potřebuju nějak zjistit začátek řetězce

Když budu mít nadpis a za tím nový řádek a pak text, tak potřebuju, aby se to nahradil br až v textu, ne hned za ].
Zbynas
Junior
Uživatelský avatar

Odeslat příspěvekod Zbynas 25. 8. 2021 17:00

Základ jsem zmáknul, dál fakt nevím :(

Kód: Vybrat vše
$text = preg_replace('/\](\S+)[\s][\n\n|\n\s\n+][\s](\S+)\[/s', ']$1<br>$2[', $text);

'/\](\S+)[\s][\n\n|\n\s\n+][\s](\S+)\[/s'

Jenže takhle se může v [\S+] nacházet klidně i [b], ale prostě tyhle tagy už to dál uvnitř obsahovat nesmí. Jak tomu řeknu že (\S+) kromě [(.*?)] ?

Díky :)
NVidia GTX 1060 6GB, Intel Core i7-2600K @ 3,4 GHz, 16 GB DDR 3
Download 100 Mbps, Upload 100 Mbps, ping 8
VINOTÉKA U FREJKA
FREJK.CZ, FREJK.SK, FREJK.COM
Zbynas
Junior
Uživatelský avatar

Odeslat příspěvekod Just_jo 26. 8. 2021 08:18

Dole v nápovědě je poznámka - k vynechání znaků se použije znak "^" takže [^abc] vynechá znaky a,b a c.

Pro plné pochopení začni jednodušší frází - podívej se jak se to chová při používání jednoduchých závorek.
Just_jo
Junior
Uživatelský avatar

Odeslat příspěvekod Zbynas 30. 8. 2021 08:47

Jo, díky, to už jsem skoro pochopil. Jenže ^ platí pro jakýkoliv ze znaků za tím uvedných, nevím, jak jak tomu říct, aby to platilo pro nějaký kus řetězce, tedy musí obsahovat více znaků v daném pořadí za sebou.

Další mega problém mám s tím, že bych chtěl definovat, co by mělo před celým replacementem být, ale nechci ho do toho zahrnovat. Příklad pro pochopení:

budu mít třeba string "test [b]test \n test[b] test"

Já chci nahradit toto: "\n",

Takže: [\]][.*?]\n+[.*?][\[] . Ale chci nahradit jen to \n ... Jde nějak říct, kde to začíná a kde končí?

Samozřejmě vím, že to jde udělat takto:

(\])(.*?)\n+(.*?)(\[) a nahradit za $1$2<br>$3$4.

To je jen příklad, já těch podmínek tam mám 10x víc a pak je to strašně složité z toho tahat určité kusy. Jednodušší by bylo, jak jsem psal výše, mít tam nějaké podmínky, pak kus, co chci nahradit a nějaké další podmínky za tím. Je nějaké jiné řešení?

Jakože bych měl [\]][.*?](\n+)[.*?][\[] a chtěl nahradit jen, co je vlastně teď v $1

A možná tak nejde ani o složitost, jako pak o to, že to nefunguje, když to nahradí nějaký kus něčeho, další opakování už vynechá to nahrazené, které by ale mělo brát zase v potaz, protože některé tagy tam ještě zůstávají ...
NVidia GTX 1060 6GB, Intel Core i7-2600K @ 3,4 GHz, 16 GB DDR 3
Download 100 Mbps, Upload 100 Mbps, ping 8
VINOTÉKA U FREJKA
FREJK.CZ, FREJK.SK, FREJK.COM
Zbynas
Junior
Uživatelský avatar

Odeslat příspěvekod Just_jo 31. 8. 2021 17:03

No a opět narážíme na to, že se sdělí jednoduchá věc a pak se z toho vyrojí komplexní obluda.

Absolutně nevím čeho chceš dosáhnout. Pokud si nenaprogramuješ nějakou svojí fci, která obstará konkrétní problém, tak jedinou, byť promyšlenou, fcí to nevyřešíš.

-- 31. 8. 2021 18:04 --

Ještě dodám

https://www.php.net/manual/en/function.nl2br.php
https://www.php.net/manual/en/function.htmlentities.php
Just_jo
Junior
Uživatelský avatar


Kdo je online

Uživatelé procházející toto fórum: Žádní registrovaní uživatelé a 0 návštevníků