Yritän korostaa hakutuloksissa esiintyvää hakusanaa värjäämällä, mutta se on hankalaa, koska haun antamissa tuloksissa voi olla bbcodea/html:llää mukana. Eli jos joku hakee vaikka hakusanalla "b", niin sitten kaikki [b]/<b>-tagit rikkoutuvat.
Tässä nyt se mitä olen tähän mennessä kokeillut:
<?php //Tämä tosiaan värjää kaiken, myös koodiosan $tulos = preg_replace("/($hakusana)/i", '<span style="background: #66ccff;">\\1</span>', $tulos); //Tämä taas ei värjää koodia, mutta ei myöskään kaikkia hakusanoja (kopioitu php.netistä: https://www.php.net/eregi_replace) $tulos = preg_replace("/(>[^<]*)($hakusana)/i", '\\1<span style="background: #66ccff;">\\1</span>', $tulos); ?>
Osaisiko kukaan jelpata? Eli pitäisi saada värjättyä hakusana, paitsi jos se esiintyy kooditagin sisällä.
<?php $sana = preg_quote($sana, "/"); $str = preg_replace("/({$sana})(?=[^<>]*(<|\$))/i", "<juttu>\\1</juttu>", $str);
Funktio preg_quote on siltä varalta, että $sana sisältää säännöllisen lausekkeen erikoismerkkejä. Itse lausekkeessa haetaan kaikki $sana-kohdat, joiden jälkeen tulee mahdollisesti lisää tagiin kuulumattomia merkkejä ja näiden jälkeen joko seuraava tagi (<) tai loppu ($). Merkintä (?=...) tarkoittaa, ettei kyseistä osaa lausekkeesta oteta mukaan itse osumaan.
Nyt rupesi toimimaan. Ainoa ongelma on, että muuttaa tekstin myös entitieettien sisältä (&, ", å...). Jos en käytä preg_replacea, lähdekoodissa on vain normaaleja kirjaimia (ä, ö...). Kun taas käytän lauseketta, niin ne muuntuvat entitieeteiksi. Missäköhän vika? Charset on UTF-8 ja teksti menee htmlspecialchars():n läpi.
Osaisiko kukaan auttaa tässä entitieettiongelmassa?
villev kirjoitti:
Osaisiko kukaan auttaa tässä entitieettiongelmassa?
Mikä niissä on ongelmana?
villev kirjoitti:
Jos en käytä preg_replacea, lähdekoodissa on vain normaaleja kirjaimia (ä, ö...). Kun taas käytän lauseketta, niin ne muuntuvat entitieeteiksi.
Tuosta saa sellaisen käsityksen, että Metabolixin koodi muttaa ä:n "ä":iksi. Sekö on ongelmana?
villev kirjoitti:
Ainoa ongelma on, että muuttaa tekstin myös entitieettien sisältä (&, ", å...).
Tuosta taas saa sellaisen käsityksen, että haettaessa "um", "ä":ista tulee jotain "&a<foo>um</foo>l;":n tyylistä.
-tossu- kirjoitti:
Tuosta taas saa sellaisen käsityksen, että haettaessa "um", "ä":ista tulee jotain "&a<foo>um</foo>l;":n tyylistä.
Periaatteessa ongelma on tämä, mutta sen voi (ehkä?) ratkaista kahdella eri tavalla: siten, että ei korosteta mitään entitieettien sisältä tai sitten pitäisi jotenkin estää se, että erikoismerkkejä ei muuteta entitieeteiksi (jonka Metabolixin koodi jostain syystä tekee).
Koodini ei mitenkään voi muuttaa erikoismerkkejä entiteeteiksi. Jos näin tapahtuu, teet sen itse aiemmin.
Ongelma on kyllä sikäli todellinen, että merkit &, < ja > on pakko muuttaa entiteeteiksi ja tämä on tehtävä ennen korostusta mutta edellinen korostuslauseke korostaa näiden sisältäkin (esim. siis lt tai amp). Seuraava korostustapa osaa käsitellä molemmat poikkeukset:
<?php $sana = preg_quote($sana, "/"); // Katkotaan aina merkkien [>;] jälkeen ja aina ennen merkkejä [<&]. $osat = preg_split("/(?<=[>;])|(?=[<&])/", $str, null, PREG_SPLIT_NO_EMPTY); $str = ""; $tagi = false; $entiteetti = false; foreach ($osat as $osa) { if ($osa[0] == "<") { $tagi = true; } if ($osa[0] == "&") { $entiteetti = true; } if ($tagi || $entiteetti) { $str .= $osa; } else { $str .= preg_replace("/$sana/", "<em>\\0</em>", $osa); } if (substr($osa, -1) == ">") { $tagi = false; } if (substr($osa, -1) == ";") { $entiteetti = false; } }
Muuten, semanttisesti sopiva tagi korostukselle on em. Voit toki muotoilla tämän CSS:llä mieleiseksesi.
Nyt toimii! Suuret kiitokset avusta sekä Metabolixille että -Tossu-:lle!
Aihe on jo aika vanha, joten et voi enää vastata siihen.