Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: Hakusana värjäys

Sivun loppuun

villev [01.10.2010 14:20:35]

#

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ä.

Metabolix [01.10.2010 15:46:46]

#

<?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.

villev [01.10.2010 18:16:56]

#

Nyt rupesi toimimaan. Ainoa ongelma on, että muuttaa tekstin myös entitieettien sisältä (&amp;, &quot;, &aring;...). 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.

villev [05.10.2010 21:15:01]

#

Osaisiko kukaan auttaa tässä entitieettiongelmassa?

-tossu- [05.10.2010 21:29:03]

#

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 "&auml;":iksi. Sekö on ongelmana?

villev kirjoitti:

Ainoa ongelma on, että muuttaa tekstin myös entitieettien sisältä (&amp;, &quot;, &aring;...).

Tuosta taas saa sellaisen käsityksen, että haettaessa "um", "&auml;":ista tulee jotain "&a<foo>um</foo>l;":n tyylistä.

villev [06.10.2010 14:00:59]

#

-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).

Metabolix [06.10.2010 16:32:14]

#

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.

villev [06.10.2010 19:20:35]

#

Nyt toimii! Suuret kiitokset avusta sekä Metabolixille että -Tossu-:lle!


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta