Søger du en specifik kategori?

 



Oprettet tir. d. 03. februar 2009 kl. 15:23

jensgram
jensgram (38.569 point)
www.jensgram.dk
Guidens karaktér
1
2
3
4
5

At klippe en streng over på det mest hensigtsmæssige sted

Formålet med denne artikel er at kaste lidt lys over, hvordan man klipper en streng over på det mest hensigtsmæssige sted.
[ Hvorfor denne artikel? ]
Et spørgsmål, der går igen i PHP-kategorien er "Hvordan finder jeg det første af en tekst?" osv. Det er derfor meningen, at denne artikel - med den dertilhørende funktion - skal forklare princippet bag.


[ Inden vi kommer for godt i gang! ]
Det havde været fedt, hvis Eksperten ville "highlighte" PHP, men det må vi tænke os til ;) Desuden er koden pænere med indrykninger, men de forsvinder også.


[ Hurtigt i gang ]
En hurtig måde at klippe en streng er ved brug af substr(). Man kan dog risikire at klippe ord over, så lad os lave en funktion, der først tjekker, om den ikke kan klippe ved et punktum:



<?php

function klip($tekst, $laengde = 50, $tolerance = 0)
{
    $punktum  = strpos(substr($tekst, $laengde - $tolerance, 2 * $tolerance), '.'); // position af punktum
    $mere      = '...'; // punktummer hvis mere tekst

    if (strlen($tekst) <= $laengde + $tolerance) {
        $slut_pos = strlen($tekst); // slutposition = slut på tekst, da denne er kortere end $laengde og $tolerance
        $mere    = ''; // ikke andet
    } elseif ($punktum !== false) {
        $slut_pos = $laengde - $tolerance + $punktum; // slutposition = punktum
    } else {
        $slut_pos = $laengde; // slutposition $laengde (ikke noget punktum indenfor $tolerance)
    }

    return substr($tekst, 0, $slut_pos) . $mere; // udskriv del + evt. punktummer
}

?>



Nu har vi en funktion der tager 1, 2 eller 3 argumenter:
$tekst: Den tekst der skal klippes.
$laengde: Længden af den tekst du vil have tilbage (50 hvis udeladt).
$tolerance: Dette angiver, hvor tæt på $laengde din tekst skal være. Som standard er $tolerance sat til 0, hvilket vil sige, at din streng bliver klippet på $laengde - uanset om der er et punktum eller ej. Sætter du derimod $tolerance til eksempelvis 10 vil funktionen lede efter et punktum mellem $laengde - 10 og $laengde + 10!

Variablen $punktum indeholder et indeks for det første punktum mellem $laengde - $tolerance og $laengde + $tolerance!

$mere indeholder det vi vil tilføje, hvis der bliver skåret noget af strengen. Tre punktummer er standard, men du kan og benytte HTML mv. Eg. $mere = '<i >[læs mere...]</i >'

If() bruges til flere ting:

1) Først tjekkes, om $tekst er kortere end $laengde + $tolerance. Er dette tilfældet så sættes $slut_pos til $tekst's længde. Desuden fjernes de tre punktummer, der skal indikere, at der er mere tekst (det er der jo ikke). Opfyldes denne betingelse ikke:
2) Vi ser nu, om der overhovedet var et punktum. I bekræftende fald sættes $slut_pos til $laengde - $tolerance (vores udgangspunkt) PLUS positionen at det første punktum ($punktum). Ellers:
3) Hvis intet af det ovenstående kunne lade sig gøre klippes der bare på $laengde uden at skelne til $tolerance.


[ Vi tester ]
Lad os teste lidt på ovenstående:



<?php

print klip('Jeg spiser tit ILD!'); // => 'Jeg spiser tit ILD!

print klip('Jeg spiser tit ILD!', 10); // => 'Jeg spiser...'

print klip('Jeg er træt af ILD. Det smager ikke som i gamle dage.', 25, 10); // => 'Jeg er træt af ILD...'

?>



Forklaring:

1) 'Jeg spiser tit ILD!' er kortere end 50 tegn, hvorfor hele strengen returneres.
2) Vi vælger at klippe ved 10 tegn (uden tolerance), så de første 10 tegn returneres ('Jeg spiser...' - strengen er jo længere, så der kommer ... på).
3) Vi har en streng med flere punktummer i. Vi vil have en streng på ca. 25 tegn (15 - 35). Dette er: 'ILD. Det smager ikke'. Der er et punktum, så $slut_pos sættes og strengen returneres med tre punktummer til sidst.


[ Del også ved mellemrum! ]
Ønsker man, at funktionen skal dele ved mellemrum, hvis den ikke lige finder et egnet puntktum, så kan man benytte:



<?php

function klip($tekst, $laengde = 50, $tolerance = 0)
{
    $punktum  = strpos(substr($tekst, $laengde - $tolerance, 2 * $tolerance), '.'); // position af punktum
    $mellemrum = strpos(substr($tekst, $laengde - $tolerance, 2 * $tolerance), ' '); // position af mellemrum
    $mere      = '...'; // punktummer hvis mere tekst

    if (strlen($tekst) <= $laengde + $tolerance) {
        $slut_pos = strlen($tekst); // slutposition = slut på tekst, da denne er kortere end $laengde og $tolerance
        $mere    = ''; // ikke andet
    } elseif ($punktum !== false) {
        $slut_pos = $laengde - $tolerance + $punktum; // slutposition = punktum
    } elseif ($mellemrum !== false) {
        $slut_pos = $laengde - $tolerance + $mellemrum; // slutposition = mellemrum
    } else {
        $slut_pos = $laengde; // slutposition $laengde (ikke noget at gøre - skær ord over)
    }

    return substr($tekst, 0, $slut_pos) . $mere; // udskriv del + evt. punktummer
}

?>



Vi har blot indsat endnu en betingelse, der testes hvis der ikke findes et punktum. Eller er funktionen som før:



<?php

print klip('Jeg er træt af ILD. Det smager ikke som i gamle dage.', 25, 10); // => 'Jeg er træt at ILD...'

print klip('Jeg er træt af ILD.', 10, 2); // => 'Jeg er træt...'

?>



Eksempel nummer to viser hvordan der ikke blev fundet et punktum (mellem tegn 8 og 12). I stedet fandtes der et mellemrum, som så blev brugt til at dele.


[ Udvidelse ]
I princippet kan du selv tilføje flere tjeks som den med mellemrum. Vil du dele ved flere tegn vil jeg dog foreslå:



<?php

function klip($tekst, $laengde = 50, $tolerance = 0)
{
    $tegn = '., :;-_'; // De tegn du gerne vil klippe ved
    $mere = '...'; // Punktummer hvis mere tekst

    if (strlen($tekst) <= $laengde + $tolerance) {
        $slut_pos = strlen($tekst); // Slutposition = slut på tekst, da denne er kortere end $laengde og $tolerance
        $mere    = ''; // Ikke andet
    } else {
        $slut_pos = $laengde; // Slutposition = længde, hvis der ikke findes et af vores tegn!
        $plads    = array(); // Array, der indeholder pladser for de forskellige tegn
        $del      = substr($tekst, $laengde - $tolerance, 2 * $tolerance); // streng indenfor $tolerance
        for ($i = 0; $i < strlen($tegn); $i++) {
            $plads[$i] = strpos($del, $tegn[$i]); // Position af det aktuelle tegn
            if ($plads[$i] !== false) {
                $slut_pos = $laengde - $tolerance + $plads[$i]; // Slutposition = position af tegn
                break; // Afslut løkke
            }
        }
    }

    return substr($tekst, 0, $slut_pos) . $mere; // udskriv del + evt. punktummer
}

?>



Her lader du $tegn indeholde de tegn, du vil dele på.
Desuden kræver Else-delen vist lidt forklaring:

1) Vi starer med at sætte slut-positionen til $laengde, da vi jo endnu ikke ved, om der findes nogle af de tegn vi vil klippe ved.
2) $plads er et array, der skal indeholde placeringen er første tilfælde af hvert tegn i $tegn.
3) $del laver vi blot, da vi så tit skal bruge indholdet indenfor tolerancen.
4) Vi laver en løkke der kører gennem hvert tegn i $tegn.
5) Positionen af det aktuelle tegn i $tegn i strengen $tekst findes
6) Hvis tegnet findes...
7) Vi sætter slut-positionen til tegnets plads.
8) Løkken afbrydes da der eksempelvis ikke er nogen grund til at lede efter mellemrum hvis vi har fundet et punktum at dele ved.


[ Afslutning ]
Dette skulle gerne have kastet lidt lys over, hvordan du laver en "appetitvækker" til dine lange tekster. Ovenstående funktion har jeg længe brugt og har ikke haft problemer - blot glæde af den.

Venlig hilsen - og god fornøjelse
- Jens Gram


PS: Jeg ved godt, at det er lidt sent, men vil bare lige gøre opmærksom på, at en formateret version af denne artikel kan findes på http://www.jensgram.dk/ (...)

Skrevet tor. d. 15. januar 2004 kl. 13:38| #1

sandbox (49.750 point)
Synd at kodeformateringen går i ged.

Skrevet tir. d. 20. januar 2004 kl. 11:07| #2


Skrevet ons. d. 28. januar 2004 kl. 18:14| #3


Skrevet ons. d. 21. juli 2004 kl. 13:45| #4

razmuz (19.431 point)
Artiklen er jo ikke til at læse!!!!!

Skrevet man. d. 27. juni 2005 kl. 02:50| #5

mysitesolution (13.889 point)
hmm griner lidt ad denne linie
print klip('Jeg spiser tit ILD!', 10); // => 'Jeg spiser...'

man har valgt at der max må være 10 tegn, men alligevel spytter den 13 tegn ud :D

hvad nu hvis teksten havde været "det spiser i", vi kan alle se den er mere end 10 tegn, men hov, så kommer der til at stå "det spiser..." hvilket er 13 tegn, hvor hele linien ville have fyldt 12 :D

Skriv en kommentar



Mest populære guides

Guidens karakter
!!!Karaktér: 3
12 stemmer
31/01 - 2011
Af: heinzdmx

Dropbox - gratis online lagerplads

Jeg vil i denne guide forklare lidt om hvad Dropbox er og også hvordan du får mest mulig plads på Dropbox. Dropbox er kort sagt en service hvor du har dine data lagt til backup på både nettet og din egen computer.
Guidens karakter
!!!Karaktér: 4
33 stemmer
02/02 - 2009
Af: jkrons

Dato- og tidsberegninger i Excel

En introduktion til simple beregninger med dato og tid i Excel. Opdateret med afsnit om beregning af tillæg.
Excel  |  Læs »
Guidens karakter
!!!Karaktér: 4
21 stemmer
06/11 - 2011
Af: fromsej

Sådan fjerner du virus og malware

Udviklingen går stærkt på "skidt"fronten, så vi har sammensat en ny og effektiv programpakke til fjernelse af det.
Virus  |  Læs »

Log ind

   

   

Seneste guides

Den gode bruger
Adgang til NAS-server via WAN
Kollektion af Batch tutorials (FJERNET)
Tilpas din YouTube afspiller


   




Tips & Tricks fra PC World

Teaser billede

Sådan fjerner du pladskrævende metadata fra dine fotos

Det er langt fra altid, at dine billeders metadata såsom kameramodel og geografisk placering er vigtige at bevare. JPG & PNG Stripper kan luge ud i billedfilerne, så de fylder meget mindre....


Anmeldelser fra PC World

Teaser billede

Test: Superlet bærbar med mange muligheder

Toshiba har med Satellite Z830 skabt en af verdens letteste ultrabooks. Den vejer 1,1 kilo, og computeren på 13 tommer ser på papiret ud til at være en oplagt rejsekammerat. Men den lave vægt har...


Seneste blogindlæg

Teaser billede

Tvangslukke spørgsmål: Hvad er den bedste løsning?

Hej Vi har mange åbne spørgsmål på Eksperten. Vi ville gerne tvangslukke dem - så et spørgsmål efter f.eks. 6 måneder lukkes. Men der er et par uklarheder som ville være gode at få lidt input til:...


Nyheder fra PC World

Teaser billede

Samsung Galaxy S III på vej

Samsungs bedst sælgende smartphone nogensinde får en efterfølger om kort tid.


Nyheder fra Computerworld

Teaser billede

Apple retter hele 51 sikkerhedshuller i Mac OS X

Apple lukker hele 51 sårbarheder i Mac OS X, hvoraf de fleste er kritiske. Se her, hvor hullerne er.


Kurser
Samarbejdspartnere

Udgiver · © 2012 IDG Danmark A/S · Hørkær 18 · 2730 Herlev · Tlf.: 77 300 300 · Fax: 77 300 301 · Brug af personoplysninger