Bevezető Levágása Reguláris Kifejezéssel

Pár napja munkahelyen (nah jó hetek óta) azzal vagyok elfoglalva, hogy kiganézzam a forrást. Rengeteg hülyeség van benne, de a legtöbb olyan, amire mindig felhívtam mindenki figyelmét, hogy ne használja. Node nem is erről akarok írni.

Ha valaki webre készít valamit és azt a nagyközönségnek, akkor szinte biztosan találkozott már a bevezető szöveg (excerpt) generálásának problémakörével. Van egy hosszabb szöveg és X karakternél el kell vágni, de szó végén. Mi a feladat tehát? Megkeresi a legutolsó olyan szót, ami még benne van a karakterszámlimitben és a következőt már nem kiírni.

Mi volt a kódban

Nem árulok el nagy titkot (üzletit biztosan nem), hogy ez egy ciklussal volt megoldva. Továbbá a mi oldalunk (ahogyan nagyon sok más) PHP alapokon fetreng. Fetreng, mert jelenleg nagyon sok baja van.

Nézzük akkor a kérdéses kódrészt:

0
(elég bután) szavakra (pont, vessző etc nincs figyelve). Végighalad a kapott tömbbön és addig adja hozzá a szavakat egy előtte létrehozott üres stringhez, amíg az túl nem lépné a korlátot.

Átaláakítás után

Miután picit elgondolkodtam egy apróbb módosítást hajtottam végre a függvényen. A teszteket nem rontottal el, így minden rendben van. Reguláris kifejezéssel viszonylag egyszerűen, egy sorban megoldható a fenti probléma. Nagy előnye, hogy a vessző, pont és társai is szóhatárolóként működnek.

Hogyan néz ki most a függvény?

1
(/^), majd ezután egy zárójelbe rakott kifejezés következik, mert hivatkozni akarunk majd rá (ez lesz a 1). Van egy karakterünk, ami bármi, de tényleg bármi lehet (a pont ugye ezt jelenti). Ez ismétlődjön legalább nullaszor, de maximum a korlátunk – 1 alkalommal. Ez azért kell, mert ezután jön a trükkös rész 😀 A sok-sok valamilyen karakter után legyen egy non-whitespace karakter, majd egy szóhatár (word boundary). Aztán persze lehet bármi, minket ez nem érdekel.

Node miért kellett az a limit - 1? Azért, mert utána még beszúrunk egy S-t, ami még egy karaktert jelent. Erre azért van szükség, mert önmagában a bármilyen karakter az szóköztől kezdve tényeg bármilyen karakter lehet. Nekünk addig kell mennünk, amíg egy szóvégnél nincs találat, így ez a S lesz majd a mi utolsó karakterünk.

No tehát ezt lecseréljük az első zárójeles rész tartalmára (nem mindtha több is lenne). Az egész előtt pedig csinálunk egy egyszerű sortörés eltávolítást, mert ugye a reguláris kifejezések sorokra alkalmazandóak (hogy miért nem az sm kapcsolókat használtam annak az az oka, hogy én a kimenetben sem akarok sortöréseket, azokat a br-ek megcsinálják).

Miben változtat ez a teljesítményen?

Most összeraktam egy fájlba a két függvényt és microtime-al megnéztem mennyi idő a futás. Így néz ki önmaga a fájl a két függvénnyel:

2

Kapcsolódó cikkek:

Balazs Nadasdi

Developer, Project Manager, Blogger, Dad... or sometihng like these

  • hozzátenném, hogy a végső állapot nálunk az hogy limit – 3 mert nem akarom, hogy az “a”, “az” szavakkal is végződhessen…

  • Érdekességnek egy alternatív megoldás: https://gist.github.com/Yitsushi/7f673d16c4e4e29b5de9

    Ez a megoldás abban másabb igazán, hogy nem függ a futási idő a szöveg hosszától. Mivel az a cikk a Reguláris kifejezésekről szól, így már nem akartam utólag belerakni ezt, így inkább csak ide rakom érdekességnek. Ez tulajdonképpen akármekkora szövegre fix idő alatt fut le. Lehet akár egy ASZF 1000+ sorral vagy egy rövidebb szonett ugyan annyi idő lesz a futás.

    Persze még bele lehet pakolni, hogy a szó végén lévő vesszőket pl törölje le, de ekkor már csak maximum limit hosszű szövegen kell dolgoztatni.

    Baromi gyors 😀 Szóval jobb mint a regexpes