reguláris

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

/**
 * Szöveg első N karakterének kinyerése
 *
 * @param int $n Hány karakter kell
 * @param string $str A string, amiből az első N karakter kell.
 * @param bool $wordwrapmod Ha null, akkor szavak közben is megvághatja  szöveget.
 *                                                      Ha true, akkor befejezi a szót, aminek a közepén vágna.
 *                                                      Ha false, akkor el sem kezdi a szót, aminek a közepén vágna.
 * @param bool $unicode Unicode karaktereket is értelmezzen.
 * @param string $more Tetszőleges szöveg, jelölés, ami akkor kerül az eredmény mögé,
 *                                              ha vágni kellett belőle.
 * @return string A levágott első N karakter
 */

function firstNChar($n, $str, $wordwrapmod = null, $unicode = true, $more = ' ...')
{
        $php53 = version_compare(PHP_VERSION, '5.3') >= 0;
        $w = $php53 ? '\w' : ($unicode ? '\p{L}\p{N}' : '\w');
        $W = $php53 ? '\W' :  '^'.$w;
        $x = $b = '';
        if ($wordwrapmod) {
                $x = '(?(?=['.$w.']+)['.$w.']+)';
        } else if (!is_null($wordwrapmod)) {
                $b = '(?=['.$W.']+)';
        }
        return preg_replace('~^(?>(.{0,'.(int)$n.'})'.$b.$x.').+$~is'.($unicode ? 'u' : ''), '$1'.$more, $str);
}

Példák

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

Eredmény

Ez egy szö ...<br />
Ez egy ...<br />
Ez egy szöveg<br />
Ez egy sz� ...<br />
Ez egy szö <a href="">&raquo;</a><br />
Megosztás/Mentés

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

A következő függvény az első N darab szót tudja kinyerni egy szövegből. Figyelembe veszi, hogy bár vessző, pont, stb... után szóköz kell, ezt nem mindenki tartja be. Ha egy mondat záródik az N. szó után, akkor a mondatzáró jelet is meghagyja. Egyébként levágja. Az N. szó után, ha az eredmény nem az egész szöveget tartalmazza, tetszőleges karakterlánc kiírható. Alapértelmezetten a három pont. Be lehet kapcsolni, hogy unicode karaktereket is tartalmaz-e a szöveg, vagy sem. Alapértelmezetten true-ra van állítva.

Függvény

/**
 * Szövegből első N szó kinyerése
 *
 * @param int $n Hány szó kell a szöveg elejéről
 * @param string $str A forrás szöveg
 * @param bool $unicode Unicode karakterek lehetnek-e a szövegben.
 * @param string $more Az eredmény szöveg mögé írt karakterlánc, ha az eredmény nem a teljes szöveg.  
 * @return string
 */

function firstNWord($n, $str, $unicode = true, $more = ' ...') {
        $php53 = version_compare(PHP_VERSION, '5.3') >= 0;
        $w = $php53 ? '\w' : ($unicode ? '\p{L}\p{N}' : '\w');
        $W = $php53 ? '\W' :  '^'.$w;
       
        return preg_replace('~^(\s*['.$w.']+'.
                        str_repeat('['.$W.']+['.$w.']+', $n-1).
                        '(?(?=[?!:;.])
                                [[:punct:]]\s*
                        ))\b(.+)$~isx'
.($unicode ? 'u' : ''), '$1'.$more, $str);
}

A függvény elején levő verzió ellenőrzés azért kellett, mert 5.3 -ban már a \w is illeszkedik ékezetes karakterre.

Példák

$nl = '<br />'.PHP_EOL;
echo firstNWord(5, "Ez egy").$nl;
echo firstNWord(5, "Ez egy.").$nl;
echo firstNWord(4, "Ez egy szöveg.Amiből megtartok 4 szót.").$nl;
echo firstNWord(3, "Ez egy szöveg. Amiből megtartok 3 szót.").$nl;
echo firstNWord(5, "Ez egy szöveg,amiből megtartok 5 szót.", true,  ' <a href="#">&raquo;</a>').$nl;
echo firstNWord(5, "Ez egy szöveg,amiből megtartok 5 szót.", false,  ' <a href="#">&raquo;</a>').$nl;

Eredmény

Ez egy<br />
Ez egy.<br />
Ez egy szöveg.Amiből ...<br />
Ez egy szöveg.  ...<br />
Ez egy szöveg,amiből megtartok <a href="#">&raquo;</a><br />
Ez egy szöveg,amib <a href="#">&raquo;</a><br />

Bár a fenti példákra működik a megoldás, nem kizárt, hogy nem tökéletes.

Megosztás/Mentés

Konfigurálható szép url-ek htaccess-el

Nos, ez már nem az első hasonló témájú bejegyzésem. De úgy gondoltam ebből sosem elég. Korábban írtam arról, hogyan lehet szép url-eket készíteni htaccess-el. Egyben arról is szólt a bejegyzés, hogy hogyan lehet többféleképpen különböző aloldalakat létrehozni. Ennek folytatásaként most mutatok egy megoldást arra, hogy egy config fájlban lehessen egyfajta mintát adni a használni kívánt url-ekre oly módon, hogy közben már azt is megadjuk, az url melyik része milyen $_GET változóba kerüljön.

Ez a megoldás feltételezi, hogy valamennyire már értünk a reguláris kifejezések használatához, de a legfontosabb tudnivalókat én is elmondom. Pár dolgot már kifejtettem a Link attribútumainak megkeresése bejegyzésemben is. És most neki is vágnék az aktuális témának.

Megosztás/Mentés

PHP reguláris kifejezések - Link attribútumainak megkeresése

A reguláris kifejezésekről nagyon sokat lehetne írni. Bevezethetném az elejétől, ahogy egyszer terveztem is, most mégis maradnék csak egy példa bemutatásánál, ami megkeresi egy html kódban az összes linket és azok összes attribútumát. Azért jó ez a példa, mert több eszköz tárgyalására is lehetőséget ad.

A preg_match függvényt fogom használni. Még lehetne az ereg függvényeket, de azokat ma már nem ajánlott.

Legyen a példa html kód a következő:

Megosztás/Mentés

Keresés és találatok kiemelése a szövegben

Kiemelő

A keresés megvalósítása még viszonylag egyszerű és kézenfekvő feladat annak, aki kicsit ért az SQL-hez. Feltéve persze, hogy a keresendő információt is SQL adatbázisban tárolja. De biztos mindenki látott már olyant, hogy a találatok ki voltak emelve valamilyen színes háttérrel. Erre írok egy nem tökéletes, de használható megoldást. Amiből már el lehet indulni egy komolyabb felé is.


A keresés még rendben van általában. De az ember szereti látni, hogy amire rákeresett, az mégis a talált szövegben hol van. Lehet persze a böngésző beépített kereső funkcióját is használni, ami firefox-ban a CTRL+F billentyű kombinációval is elérhető, de megspórolhatunk a felhasználónak ennyi többletmunkát.

Megosztás/Mentés

Szövegben url-ek linkké alakítása automatikusan php-vel

Szokás fórumokon, vendégkönyvekben a beírt url-eket automatikusan felismertetni és átalakítani kattintható linkké. Erre jól használhatók a reguláris kifejezések. Az első példa rövid, de felismeri a linkeket, amik http-vel, https-el, www-el, wap-al kezdődnek. Viszont ha vessző kerül a végére, mert épp egy tagmondat végén van, vagy pont, esetleg felkiáltó jel, akkor az is bekerül a linkbe.

<?php
$szoveg = "Egy szövegben lehet link https-el kezdődve: https://www.google.com/accounts/ServiceLogin?service=mail
vagy csak http-vel. http://rimelek.hu,
 www.phpstudio.hu "
;

$szoveg = preg_replace("#(\s*)((http(s?)://)|(www\.|wap\.))(\S+\.\S+)#is", "\\1<a href=\"http\\4://\\5\\6\" target='_blank'>\\2\\6</a>", $szoveg);
print $szoveg;
?>

A másik megoldás bonyolultabb, de az írásjeles hibát is megoldja:

<?php
function url2link($matches)
{
        $i = strlen($matches[0]);
        $szoveg = trim($matches[0],',.!');
        $j = strlen($szoveg);
        return preg_replace("#(\s*)(http(s?)://)?(.*)#is",
                "\\1<a href=\"http\\3://\\4\" target='_blank'>\\2\\4</a>",
                $szoveg).substr($matches[0],$i-1,$i-$j);
}

$szoveg = preg_replace_callback("#(\s*)((http(s?)://)|(www\.|wap\.))(\S+\.\S+)#is",'url2link',$szoveg);
print $szoveg;
?>

Megosztás/Mentés