Bevezető szöveg generálása PHP-vel

A weblaboron merült fel egy kérdés: hogyan lehet szépen megoldani, hogy egy hosszú szövegből előállítsunk egy rövidebb bevezetőt, aminek korlátozva van a maximális hossza, és szóhatárnál végződik. Itt adok rá egy megoldást.

Először is a megoldás: RegExp.

1
\A(.{0,60})\b

Ez a RegExp a következőt jelenti: vegyünk egy 0 és 60 karakter hosszú (rész)sztringet (.{0, 60}), amely az eredeti sztring elején kezdődik (\A) és szóhatárnál végződik (\b). A RegExp motor ezt többnyire elég gyorsan meg fogja találni, mivel mohón keresi, tehát a 60. karaktertől elindul visszafelé, és megkeresi a legelső karaktert, amely után szóhatár van (szóhatár alatt szó kezdetet és véget egyaránt értünk). Az első probléma ezzel, hogy szóközre (pontosabban white-space karakterre) végződő sztringet is kaphatunk (szó kezdet eset), úgyhogy ezt a kódból kezelnünk kell majd.
Írjunk is köré egy wrappert:

1
2
3
4
5
6
7
8
<?php
function intro($string, $maxLength = 30, $template = '%1$s')
{
	if (preg_match(sprintf('/\A(.{0,%d})\b/si', $maxLength), $string, $result)) {
		return sprintf($template, rtrim($result[0]));
	}
	return '';
}

Végülis ennyi a függvény: dinamikusan beszúrjuk a kívánt maximális hosszt a fenti reguláris kifejezésbe, aztán ráeresztjük a sztringre, majd a kapott stringet behelyettesítjük a(z opcionálisan megadható) sablonba.

Példa a használatára:

1
echo intro('Árvíztűrő tükörfúrógép, asdasd és foobar foo baz bar illetve lorem ipsum', 30, '%1$s ...');

És a kiemenet:

Árvíztűrő tükörfúrógép, asdasd ...

17 HOZZÁSZÓLÁS

  1. Sziasztok!

    És mit kellene akkor csinálni, ha ez a szöveg tele van formázásokkal?
    Hogy tudnám a html-t text-é alakítani?

    Köszönjük ezt a kis script-et :)

  2. Erre tökéletesen bevált recept nincs (mármint a markup-mentesítésre), viszont bevezetőt főleg olyan dolgokhoz szokás csinálni, amit admin felületen raksz fel és nem a userek küldenek be, egy strip_tags bőven elég (ha meg usertől származik az adat, amiről készül a bevezető, akkor keresel google-vel egy „remove html regexp”-et és kapsz pár találatot).

    Így a teljes hívás:

    1
    2
    
    $szoveg = 'asdasdfoobar';
    intro(strip_tags($szoveg), 30, '%1$s');

    BlackY

  3. Én ezt a függvény használom a html formázások eltávolítására:

    function html2text($dokumentum) {
    $mit = array („‘<script[^.*?’si”,
    „‘<[\/\!]*?[^]*?>’si”,
    „‘([\r\n])[\s]+'”,
    „‘&(quot|#34);’i”,
    „‘&(amp|#38);’i”,
    „‘&(lt|#60);’i”,
    „‘&(gt|#62);’i”,
    „‘&(nbsp|#160);’i”,
    „‘&(iexcl|#161);’i”,
    „‘&(cent|#162);’i”,
    „‘&(pound|#163);’i”,
    „‘&(copy|#169);’i”,
    „‘&#(\d+);’e”);

    $mire = array („”,
    „”,
    ” „,
    „\””,
    „&”,
    „”,
    ” „,
    chr(161),
    chr(162),
    chr(163),
    chr(169),
    „chr(\\1)”);
    return htmlspecialchars(preg_replace ($mit, $mire, $dokumentum));
    }

  4. Köszönjük eme függvényt, pofás és kicsi. Teljesen jól használható, ajánlom mindenki figyelmébe.

  5. Blacky! Ennek meg tudnád írni az Unicode karaktereket is támogató verzióját?

  6. Ha a preg_match-nél beadod még az u kapcsolót (tehát a vége /si helyett /usi), akkor már azzal is működni fog.

    BlackY

  7. Úgy próbáltam én is, de nem működött. Az unicode karakternél vette a szó végét és ott vágta el, meg hasonlók. Próbáld ki!

  8. És tényleg…
    Viszont ha a \b (szóhatárt) lecseréled egy (\s|\Z) (whitespace karakter vagy sor/input vége), akkor ugyanazt a működést kéne kapnod. Cserébe ezzel vannak csúnya esetek, amik a sima szóhatárnál nincsenek:

    Pl.: ha írásjelre végződik a kapott rész, akkor hülyén néz ki, hogy a levágott szöveged ilyen: „Árvíztűrő tükörfúrógép,”, pont-kérdőjel-felkiáltójelnél ez még jól is jönne, de így. A trim-be mondjuk fel lehetne venni a karaktereket, amik hülyén néznek ki egy bevezető szöveg végén, csak szép hosszú lenne a lista.

    Azt lehetne csinálni, hogy a . helyett felsorolod a magyar betűket, a \b-t lecseréled egy negative lookahead-re (^([A-Záéűúőóüö]{0,30})(?![A-Záéűúőóüö])), az viszont nem csúnyán néz ki.

    BlackY

  9. Kicsit módosítva…
    ************************************
    function intro($string, $maxLength = 30, $template = ‘%1$s’)
    { //formázás kivétele a szövegből
    $string = strip_tags($string);
    //módosított reguláris kifejezés
    $format=’/\A(.{0,%d})[\s]\b/siu’;
    if (preg_match(sprintf($format, $maxLength), $string, $result)) {
    //if (preg_match(sprintf(‘/\A(.{0,%d})\b/si’, $maxLength), $string, $result)) {
    return sprintf($template, rtrim($result[0]));
    }
    return ”;
    }
    *************************

  10. function strcut($text,$length,$dots=true)
    {
    if (preg_match(‘/^(.{0,’ . $length . ‘})(?:,|;|\.|\?|!|\s|$)/su’,$text,$matches)) return $matches[1] . ($dots && strlen($matches[1])<strlen($text) ? ' …' : '');
    else return;
    }

  11. Nekem „lnorby” megoldása tökéletesen működik, viszont a vesszőre (,) vegződő vágott sztringeket elég csúnyán jeleníti meg (asdasd,…), s egyenlőre nem találtam rá megoldást (sajnos annyire nem értek még a Regexhez). :( Van esetleg valami ötlet?

  12. És így?
    function strcut($string,$maxLength,$dots=true)
    {
    if(preg_match(‘/^(.{0,’ . $maxLength . ‘})(?:,|;|\.|\?|!|\s|$)/su’,$string,$matches))
    //return $matches[1] . ($dots && strlen($matches[1])<strlen($string) ? ' …' : '');
    return str_replace(",", "", $matches[1]).($dots && strlen($matches[1])<strlen($string) ? ' …' : '');
    else
    return;
    }

  13. Ha csak az utolsót(a pontok előttit), akkor
    return substr_replace($matches[1], ”, strlen($matches[1])-1, 1).($dots && strlen($matches[1])<strlen($string) ? '…' : '');

  14. Mit szólsz az „rtrim”-hez? (Igen, csak a pontok előtti vessző nem kell…)

    1
    
    return rtrim($matches[1], ',') . ($dots &amp;&amp; strlen($matches[1])&lt;strlen($text) ? &#039;...&#039; : &#039;&#039;);

HOZZÁSZÓLOK A CIKKHEZ

Kérjük, írja be véleményét!
írja be ide nevét