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 ...
Kapcsolódó bejegyzések:
  • A következőkben egy olyan, általam írt PHP-s függvényt szeretnék bemutatni, amellyel könnyedén és egyszerűen készíthetünk magunknak olyan oldalt, amely támogatja …

  • Minap belefutottam egy olyan feladatba, hogy több száz soros szövegállományt kellett letakarítani a felesleges részektől, hogy megkapjak egy listát.A lis …

  • Amikor regisztrálsz egy weboldalon, az oldal általában leellenőrzi, hogy a beírt e-mail címed szabályos formátumú-e. Ehhez szükségünk van egy sztringre (pl.: $em …

  • Ezen tutoriálom segítségével megtanulhatja mindenki a következő BBkódokat előállítani:Vastag szöveg Aláhúzott szöveg Dőlt szöveg Képek HTML kód kilövés …

  • Korábban már volt egy reguláris kifejezésekkel kapcsolatos cikk ( Reguláris kifejezések avagy regexp ), most egy online tesztelő eszközt szeretnék hozzá ajánlani …

A cikket beküldte: BlackY ()

17 hozzászólás

  1. BlackY says:

    http://www.php.net/sprintf

    Az ott nem l (kis L), hanem 1 (egy, szám). Amúgy azt jelenti, hogy az első paraméter (1) sztringként (s) kerüljön oda.

    BlackY

  2. crash says:

    a %l$s a templatenel mit jelent? ;]

  3. Tódi says:

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

  4. BlackY says:

    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

  5. Whiteford says:

    É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));
    }

  6. cyrus says:

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

  7. lnorby says:

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

  8. BlackY says:

    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

  9. lnorby says:

    Ú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!

  10. BlackY says:

    É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

  11. szabofe says:

    Egy kicsit módosítva…

  12. szabofe says:

    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 ”;
    }
    *************************

  13. lnorby says:

    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;
    }

  14. Tibi says:

    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?

  15. szabofe says:

    É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;
    }

  16. szabofe says:

    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) ? '…' : '');

  17. Tibi says:

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

Szólj hozzá
a Bevezető szöveg generálása PHP-vel c. bejegyzéshez

- Engedélyezett HTML elemek: <a> <em> <strong> <ul> <ol> <li>
- Forráskód beküldéséhez tedd a kódot ezek közé: <pre lang="php" line="1">Kódrészlet helye itt</pre>