Autor Zpráva
Tomáš123
Profil
Zdravím, po včerajšku* (poznámka na dne) som sa rozhodol začať s regulárnymi výrazmi. Rozhodol som sa učiť na systéme zvýrazňovania syntaxe. Poskladal som toto:
<meta charset="UTF-8">
<style>
    .sign {color: #7DB9E8}
    .atribute {color: #B6D673}
    .value {color: #D33939}
</style>
<?php
    $string = "<p class=\"info\">Nejaký obsah</p>";
    $string = preg_replace('/<(.+) ((.+)=\"(.+)\")?>((.+)<\/(.+)>)?/', '<span class="sign">&lt;\\1 <span class="atribute">\\3="<span class="value">\\4</span>"</span>&gt;</span>\\6<span class="sign">&lt;/\\1&gt;</span>', $string);
    echo $string;
?>
Neviem prísť na to, ako sa vysporiadať s nepárovými HTML značkami. Stále sa mi na konci zobrazí aspoň </(\\1)>. Ak by som sa odkázal na referenciu číslo 5, kde je prípadný obsah a koniec prvku, neviem koncovú značku zafarbiť.

Vedeli by ste mi prosím poradiť, ako upraviť regulárny výraz (pravdepodobne je dlhší než je potrebné, tak to prosím skracujte iba tak, aby som tomu stíhal rozumieť)?

* Ak chcete, môžte tu premiestniť aj diskusiu zo včerajška.
juriad
Profil
Postavit zvýrazňovač je hodně těžké. Regulární výrazy se mohou použít na jednoduché tagy, nikoli celé elementy. Máš tam problém s rekurzí - element může obsahovat další element; to je sice řešitelné, ale nepraktické, protože v HTML je spousta počátečních a koncových značek nepovinných.

Toto je validní stránka; hodně štěstí:
<!doctype html>
<title>Titulek</title>
</head>
</body>
</html>

A když pomineme nepovinnost, je stále problém s porouchaných HTML.
Nejlepší možností, jak zvýrazňovat na serveru je postavit DOM a tím následně traverzovat. PHP má http://php.net/manual/en/domdocument.loadhtml.php, nebo existuje spousta knihoven.
Tomáš123
Profil
juriad:
Viem, že to bude ťažké a nemám v pláne to hneď dokončiť. Máš ale pravdu, pre začiatok to nie je najvhodnejšie.

Mám ohľadom regulárnych výrazov dve otázky:
Často vídam (?*) resp. (.?*). Čo to, prosím, znamená?

Taktiež vo výukových materiáloch na pavucina.webark.cz vidíme, že sa autor kódu odvoláva na spätnú referenciu už v prvom parametri funkcie. Keď som to ale skúšal ja, nefungovalo mi to. Skúšal som to takto:
<(.+) ((.+)="(.+)")?>((.+)<\/${1}>)?
A vypísalo mi to upozornenie: Compilation failed: nothing to repeat at offset 32.
Aj takto
<(.+) ((.+)="(.+)")?>((.+)<\/\\1>)?
Ale zafarbenie sa nezmenilo a skript si ľahko koncovú značku domyslel.
Príklad:
$string = "<p class=\"info\">b</a>";
Výsledok (so zafarbením podobným tomuto):
<p class="info"></p>b
Ako teda správne používať spätné referencie?
juriad
Profil
Tomáš123:
Často vídam (?*) resp. (.?*). Čo to, prosím, znamená?
Ani jedno jsi nemohl vidět.
Existuje však:
.*?
kde otazník funguje jako modifikátor hvězdičky a dělá z ní nežravou variantu. Například to „a“ v regexu
/.*?a.*/
v textu „baaaaab“ je to první „a“. Bez hvězdičky by to bylo to poslední.

Pak také existují roztodivné skupiny:
(?:re)
v tomto případě jde o skupinu, která netvoří zpětnou referenci. Chová se to stejně jako:
(re)
jen \1 neexistuje.
Těch variant skupin je hodně (look ahead, look back, jejich negace).

Ano, můžeš se odvolat na referenci už ve výrazu:
/(.)(.).\2\1/
najde slova „kajak“, „madam“, ale ne „string“ nebo „class“.

To zpětné lomítko tam má být v regexu jen jedno. Ale v PHP i uvnitř apostrofů existují dvě escape sekvence (\' a \\), tedy dvě zpětná lomítka uvnitř apostrofů bude ve výsledku jedn zpětné lomítko.
Ten poslední příklad je podle mě správně. Ono si to nedomyslelo </p>, ale myslelo si, že jde o nepárový tag a chyba při výpise, která nekontroluje existenci \5 tam tu značku doplnila. Samotné regexy jsou krátké na rozlišení, zda nějaká část něco našla v nahrazovací části. Na to bys musel použít callback a v tom prozkoumat hodnotu skupiny číslo 5.
Tomáš123
Profil
juriad:
Dobre, ďakujem, tak ja tú prax ešte odložím, niečo si o tom naštudujem a o pár týždňov, možno mesiacov keď už budem rozumieť, čo sa mi snažíš/te vysvetliť sa do toho ponorím. :-)
lionel messi
Profil
Tomáš123:
niečo si o tom naštudujem
Takmer kompletný prehľad syntaxe s jednoduchými príkladmi nájdeš na www.regularnivyrazy.info/shrnuti-syntaxe.html#.VOpG0hafVyU (po zdieľaní webu na Twitteri/Facebooku je dostupná aj PDF verzia).

Na testovanie regulárnych výrazov môžeš použiť rôzne programy, množstvo z nich je mimoriadne prepracovaných, mnohé platené, spomedzi tých zdarma sa mi celkom osvedčil The Regex Coach.
juriad
Profil
Já raději používám anglický web http://www.regular-expressions.info/, kde je vše podrobně popsáno včetně těch pokročilejších partií, na které člověk denně nenarazí.
Tomáš123
Profil
lionel messi, juriad:
Ďakujem

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: