Szöveg első N karakterének kinyerése reguláris kifejezéssel, php-val

Az előző bejegyzésemhez hasonló megoldást mutatok, csak most nem adott számú szót vág le a függvény egy szövegből, hanem karaktereket. Szintén állítható, hogy mi kerüljön a levágott szöveg végére, ha volt mit vágni. És szintén megadható, hogy unicode szövegként legyen-e értelmezve a megadott string. Itt mégis a lényegesebb paramétere a függvénynek a 3. paraméter. Ha egy szövegben pont egy szót kéne ketté vágni, nem biztos, hogy jól mutat. Vegyük példának azt a szöveget, hogy: „Mi ez a foszfor?”. Ennek az első 11 karakterét levágva fixen elég érdekes eredményt kapnánk, ami nem biztos, hogy megengedhető. A következő függvény harmadik paraméterével szabályozható, hogy a szövegben a félbevágott szavakat be kell-e fejezni, vagy esetleg el sem kell kezdeni. Netán nyugodtan meg lehet vágni bárhol. A megoldás most is reguláris kifejezésekkel működik, bár az mb_substr függvényt is használhattam volna.

Függvény

  1. /**
  2.  * Szöveg első N karakterének kinyerése
  3.  *
  4.  * @param int $n Hány karakter kell
  5.  * @param string $str A string, amiből az első N karakter kell.
  6.  * @param bool $wordwrapmod Ha null, akkor szavak közben is megvághatja  szöveget.
  7.  *                                                      Ha true, akkor befejezi a szót, aminek a közepén vágna.
  8.  *                                                      Ha false, akkor el sem kezdi a szót, aminek a közepén vágna.
  9.  * @param bool $unicode Unicode karaktereket is értelmezzen.
  10.  * @param string $more Tetszőleges szöveg, jelölés, ami akkor kerül az eredmény mögé,
  11.  *                                              ha vágni kellett belőle.
  12.  * @return string A levágott első N karakter
  13.  */
  14. function firstNChar($n, $str, $wordwrapmod = null, $unicode = true, $more = ' ...')
  15. {
  16.         $php53 = version_compare(PHP_VERSION, '5.3') >= 0;
  17.         $w = $php53 ? '\w' : ($unicode ? '\p{L}\p{N}' : '\w');
  18.         $W = $php53 ? '\W' :  '^'.$w;
  19.         $x = $b = '';
  20.         if ($wordwrapmod) {
  21.                 $x = '(?(?=['.$w.']+)['.$w.']+)';
  22.         } else if (!is_null($wordwrapmod)) {
  23.                 $b = '(?=['.$W.']+)';
  24.         }
  25.         return preg_replace('~^(?>(.{0,'.(int)$n.'})'.$b.$x.').+$~is'.($unicode ? 'u' : ''), '$1'.$more, $str);
  26. }

Példák

  1. $nl = '<br />'.PHP_EOL;
  2. echo firstNChar(10, "Ez egy szöveg").$nl;
  3. echo firstNChar(10, "Ez egy szöveg", false).$nl;
  4. echo firstNChar(10, "Ez egy szöveg", true).$nl;
  5. echo firstNChar(10, "Ez egy szöveg", null, false).$nl;
  6. echo firstNChar(10, "Ez egy szöveg", null, true, ' <a href="">&raquo;</a>').$nl;

Eredmény

  1. Ez egy szö ...<br />
  2. Ez egy ...<br />
  3. Ez egy szöveg<br />
  4. Ez egy sz� ...<br />
  5. Ez egy szö <a href="">&raquo;</a><br />
Kategóriák: 
Megosztás/Mentés

Hozzászólások

Brown ügynök képe

Szia!

A blogbejegyzések első 500 karakterét szeretném megjeleníteni. A 3. példa megfelelő lenne, ha a bejegyzés nem tartalmazna paragrafus tageket. Ha 500 karakternél hosszabb egy bejegyzés akkor a paragrafus lezáró tag nem jelenik meg. Ezt próbáltam orvosolni ezzel a kóddal:

preg_match("/<\/p>/",substr(wordwrap($str, 0,500), -4) != '</p>') ? $more = "" : $more = "</p>";

Sajnos így akkor is beszúrja a lezáró taget, ha a bekezdés lezáró tagje mégis belefért. ( Mert a wordwrap nem veszi figyelembe a tageket).

Bármilyen megoldás érdekel. :)

Rimelek képe

Helló. A megoldásom csak egyszerű szövegekre alkalmas. Ha neked az első bekezdés első 500 karaktere kell, előbb az első bekezdés tartalmát kell regexp-pel megkeresned. És csak azt vágni. De ha abban is van más html, akkor megint bonyolultabb a dolgod. Így két lehetőséged van. Az egyik, hogy a htmlt teljesen kiszűröd, és csak azt rövidíted 500 karakteresre. Ezt a strip_tags függvénnyel tudod megtenni. A másik, hogy a bevezetőt külön tárolod.

Amit te próbáltál az több okból is hibás. Először is nem garancia, hogy az utolsó 4 karakter lesz a bekezdészáró. Másodszor ha már az utolsó karaktert karaktereket ellenőrzöd, nem kell preg_match. És ha használsz preg_match-t, akkor annak második paramétere nem logikai érték kell legyen, mint esetedben, hanem string.

Brown ügynök képe

Akkor marad az, hogy külön letárolom. Az nem befolyásolja az oldal betöltési sebességét. :)

Új hozzászólás