Zdobądź pierwsze n znaków ciągu

320

Jak mogę uzyskać pierwsze n znaków ciągu w PHP? Jaki jest najszybszy sposób przycięcia ciągu do określonej liczby znaków i dodania „...” w razie potrzeby?

Alex
źródło
5
lepiej byłoby użyć znaku elipsy…
Keet,
1
sprawdź moją odpowiedź, jeśli chcesz uniknąć wycinania słów.
TechNyquist
Spróbuj tego linku, może Ci pomóc ... stackoverflow.com/a/26098951/3944217
edCoder

Odpowiedzi:

577
//The simple version for 10 Characters from the beginning of the string
$string = substr($string,0,10).'...';

Aktualizacja:

W oparciu o sugestię sprawdzania długości (a także zapewnienia podobnych długości na przyciętych i nieobciętych ciągach):

$string = (strlen($string) > 13) ? substr($string,0,10).'...' : $string;

Otrzymasz ciąg maksymalnie 13 znaków; 13 (lub mniej) normalnych znaków lub 10 znaków, po których następuje „...”

Aktualizacja 2:

Lub jako funkcja:

function truncate($string, $length, $dots = "...") {
    return (strlen($string) > $length) ? substr($string, 0, $length - strlen($dots)) . $dots : $string;
}

Aktualizacja 3:

Minęło trochę czasu, odkąd napisałem tę odpowiedź i tak naprawdę nie używam już tego kodu. Wolę tę funkcję, która zapobiega łamaniu łańcucha w środku słowa za pomocą wordwrapfunkcji:

function truncate($string,$length=100,$append="…") {
  $string = trim($string);

  if(strlen($string) > $length) {
    $string = wordwrap($string, $length);
    $string = explode("\n", $string, 2);
    $string = $string[0] . $append;
  }

  return $string;
}
Brendan Bullen
źródło
11
najlepiej byłoby zastąpić wielokropkiem (…) zamiast 3 kropkami (...)
Keet
3
Uwielbiam to, ale zmieniłem to i użyj następującego polecenia, aby usunąć białe znaki na końcu: $ string = substr (trim ($ string), 0,10) .'... '; W ten sposób otrzymujesz coś w stylu „lubię ...” zamiast „lubię ...”.
Kenton de Jong,
28
„hellip” - zrozumiałem, że nie mówimy o adresie IP szatana
Lucas Bernardo de Sousa
2
Aktualizacja 3 jest najbardziej pomocna.
Milkovsky
Jeśli długość zwracanego ciągu jest ograniczona, to czy wiersz 5 aktualizacji 3 nie powinien być $string = wordwrap($string, $length - sizeof($append)); ?
Michael Crenshaw
114

Ta funkcjonalność została wbudowana w PHP od wersji 4.0.6. Zobacz dokumenty .

echo mb_strimwidth('Hello World', 0, 10, '...');

// outputs Hello W...

Zauważ, że trimmarker(elipsa powyżej) są uwzględnione w długości obciętej.

bruchowski
źródło
4
Działa dla mnie idealnie. Najlepsza odpowiedź nie działała i cieszę się, że nie, ponieważ ciągle przewijałem i znalazłem ten klejnot.
Eduardo
Dziękuję, zawsze używałem tej dłuższej i starszej metody!
gr3g
1
Dan, możesz chcieć sprecyzować, która część najwyższej odpowiedzi nie zadziałała. Funkcja truncate () działała dla mnie idealnie, a przewagą tej odpowiedzi nad odpowiedzią Bruchowskiego jest to, że łamie ona granice słów; zakładając, że troszczysz się o takie rzeczy.
pdwalker
2
dobry chwyt! wielu doświadczonych programistów PHP nie wie o tej funkcji :)
jroi_web
1
Najlepsza (obecnie) odpowiedź ( stackoverflow.com/a/3161830/236306 ) nic nie zrobiła (tak jakby w ogóle nie użyłem fn). Nie wiem dlaczego. Ta odpowiedź wydaje się jednak idealna i ma dodatkową zaletę pracy.
Alan
15

Rozszerzenie Multibyte może się przydać, jeśli potrzebujesz kontroli nad zestawem znaków.

$charset = 'UTF-8';
$length = 10;
$string = 'Hai to yoo! I like yoo soo!';
if(mb_strlen($string, $charset) > $length) {
  $string = mb_substr($string, 0, $length - 3, $charset) . '...';
}
Emil Vikström
źródło
Ten kod dodaje trzy kropki do ciągu? mój kod ma tag link <a>, a kiedy go połączę, połączy go razem z trzema kropkami, które otrzymają inną wartość.
fello
9

czasami trzeba ograniczyć ciąg do ostatniego pełnego słowa, tzn .: nie chcesz, aby ostatnie słowo zostało złamane, zamiast tego zatrzymaj się na drugim ostatnim słowie.

np .: musimy ograniczyć „This is my String” do 6 znaków, ale zamiast „This ja ...” chcemy, aby to był „This…”, tzn. w ostatnim słowie pominiemy te łamane litery.

uff, jestem kiepski w wyjaśnianiu, oto kod.

class Fun {

    public function limit_text($text, $len) {
        if (strlen($text) < $len) {
            return $text;
        }
        $text_words = explode(' ', $text);
        $out = null;


        foreach ($text_words as $word) {
            if ((strlen($word) > $len) && $out == null) {

                return substr($word, 0, $len) . "...";
            }
            if ((strlen($out) + strlen($word)) > $len) {
                return $out . "...";
            }
            $out.=" " . $word;
        }
        return $out;
    }

}
MortalViews
źródło
9

Jeśli chcesz wyciąć uważając, aby nie dzielić słów, możesz wykonać następujące czynności

function ellipse($str,$n_chars,$crop_str=' [...]')
{
    $buff=strip_tags($str);
    if(strlen($buff) > $n_chars)
    {
        $cut_index=strpos($buff,' ',$n_chars);
        $buff=substr($buff,0,($cut_index===false? $n_chars: $cut_index+1)).$crop_str;
    }
    return $buff;
}

jeśli $ str jest krótszy niż $ n_chars zwraca go nietkniętym.

Jeśli $ str jest równe $ n_chars, zwraca je również.

jeśli $ str jest dłuższy niż $ n_chars, to szuka następnej przestrzeni do wycięcia lub (jeśli nie ma więcej spacji do końca) $ str zostaje niegrzecznie przecięta w $ n_chars.

UWAGA: pamiętaj, że ta metoda usunie wszystkie tagi w przypadku HTML.

TechNyquist
źródło
8

Struktura Codeigniter zawiera pomocnik do tego, zwany „pomocnikiem tekstowym”. Oto dokumentacja z podręcznika użytkownika Codeigniter, który ma zastosowanie: http://codeigniter.com/user_guide/helpers/text_helper.html (wystarczy przeczytać sekcje word_limiter i character_limiter). Oto dwie funkcje związane z Twoim pytaniem:

if ( ! function_exists('word_limiter'))
{
    function word_limiter($str, $limit = 100, $end_char = '&#8230;')
    {
        if (trim($str) == '')
        {
            return $str;
        }

        preg_match('/^\s*+(?:\S++\s*+){1,'.(int) $limit.'}/', $str, $matches);

        if (strlen($str) == strlen($matches[0]))
        {
            $end_char = '';
        }

        return rtrim($matches[0]).$end_char;
    }
}

I

if ( ! function_exists('character_limiter'))
{
    function character_limiter($str, $n = 500, $end_char = '&#8230;')
    {
        if (strlen($str) < $n)
        {
            return $str;
        }

        $str = preg_replace("/\s+/", ' ', str_replace(array("\r\n", "\r", "\n"), ' ', $str));

        if (strlen($str) <= $n)
        {
            return $str;
        }

        $out = "";
        foreach (explode(' ', trim($str)) as $val)
        {
            $out .= $val.' ';

            if (strlen($out) >= $n)
            {
                $out = trim($out);
                return (strlen($out) == strlen($str)) ? $out : $out.$end_char;
            }       
        }
    }
}
Mateusz
źródło
4

Użyj podciągów

http://php.net/manual/en/function.substr.php

$foo = substr("abcde",0, 3) . "...";
Dlongnecker
źródło
3
Ten kod zawsze doda ... do ciągu, którego nie chciał.
TravisO,
Masz absolutną rację, a ja odpowiednio zredagowałem odpowiedź. (Poprawiona odpowiedź oczekuje obecnie na recenzję SO)
Chaya Cooper
3
if(strlen($text) > 10)
     $text = substr($text,0,10) . "...";
HCL
źródło
Od @Brendon Bullen powyżej .. $ string = (strlen ($ string)> 13)? substr ($ string, 0,10) .'... ': $ string; Miły !
MarcoZen
1

Użyłem funkcji:

function cutAfter($string, $len = 30, $append = '...') {
        return (strlen($string) > $len) ? 
          substr($string, 0, $len - strlen($append)) . $append : 
          $string;
}

Zobacz to w akcji .

Benjamin Crouzier
źródło
1

To jest to, co robie

    function cutat($num, $tt){
        if (mb_strlen($tt)>$num){
            $tt=mb_substr($tt,0,$num-2).'...';
        }
        return $tt;
    }

gdzie $ num oznacza liczbę znaków, a $ tt ciąg do manipulacji.

Christoz
źródło
1

Opracowałem funkcję do tego zastosowania

 function str_short($string,$limit)
        {
            $len=strlen($string);
            if($len>$limit)
            {
             $to_sub=$len-$limit;
             $crop_temp=substr($string,0,-$to_sub);
             return $crop_len=$crop_temp."...";
            }
            else
            {
                return $string;
            }
        }

po prostu wywołujesz funkcję z ciągiem i ograniczeniem,
np .: str_short("hahahahahah",5);
tnie cięciwy i doda „...” na końcu
:)

Saikelu
źródło
1

Aby utworzyć w ramach funkcji (do wielokrotnego użytku) i dynamicznie ograniczonej długości, użyj:

function string_length_cutoff($string, $limit, $subtext = '...')
{
    return (strlen($string) > $limit) ? substr($string, 0, ($limit-strlen(subtext))).$subtext : $string;
}

// example usage:
echo string_length_cutoff('Michelle Lee Hammontree-Garcia', 26);

// or (for custom substitution text
echo string_length_cutoff('Michelle Lee Hammontree-Garcia', 26, '..');
tfont
źródło
1

Najlepiej jest wyodrębnić kod w taki sposób (zauważ, że limit jest opcjonalny i domyślnie wynosi 10):

print limit($string);


function limit($var, $limit=10)
{
    if ( strlen($var) > $limit )
    {
        return substr($string, 0, $limit) . '...';
    }
    else
    {
        return $var;
    }
}
TravisO
źródło
1
To nie zadziała, ponieważ trim () już istnieje.
Gordon,
Czy mógłby wyjaśnić, dlaczego takie podejście jest najlepsze, a nie tylko twierdzenie, że tak jest?
Robert
1
@Robert jest prosty, a abstrakcja oznacza, że ​​nie musisz ciągle wpisywać kodu. A co najważniejsze, jeśli znajdziesz lepszy sposób na zrobienie tego lub chcesz czegoś bardziej złożonego, zmienisz tę funkcję 1 zamiast 50 fragmentów kodu.
TravisO,
2
Dlaczego funkcja jest pisana wielkimi literami?
Carlo
Poprawka: substr z $ var, a nie $ string. Przetestuj $limit + 3, aby nie przyciąć struny tuż ponad limit. W zależności od aplikacji (np. Danych wyjściowych HTML) zastanów się nad użyciem encji &hellip;(typograficznie bardziej przyjemnej). Jak zasugerowano wcześniej, przytnij wszelkie nie-litery z końca (skróconego) łańcucha przed dołączeniem wielokropka. Na koniec uważaj, jeśli jesteś w środowisku wielobajtowym (np. UTF-8) - nie możesz używać strlen () i substr ().
Phil Perry
1

Nie jestem pewien, czy jest to najszybsze rozwiązanie, ale wygląda na to, że jest najkrótsze:

$result = current(explode("\n", wordwrap($str, $width, "...\n")));

PS Zobacz kilka przykładów tutaj https://stackoverflow.com/a/17852480/131337

Sergiy Sokolenko
źródło
0

byłoby substr (), najlepiej najpierw sprawdzić długość łańcucha

$str = 'someLongString';
$max = 7;

if(strlen($str) > $max) {
   $str = substr($str, 0, $max) . '...';
}

zawijanie słów nie przycina łańcucha, po prostu go rozdziela ...

tsgrasser
źródło
0

$ szerokość = 10;

$a = preg_replace ("~^(.{{$width}})(.+)~", '\\1…', $a);

lub z zawijaniem wyrazów

$a = preg_replace ("~^(.{1,${width}}\b)(.+)~", '\\1…', $a);
akond
źródło
0

to rozwiązanie nie wycina słów, doda trzy kropki po pierwszym spacji. Zredagowałem rozwiązanie @ Raccoon29 i zastąpiłem wszystkie funkcje funkcjami mb_, aby działało to we wszystkich językach, takich jak arabski

function cut_string($str, $n_chars, $crop_str = '...') {
    $buff = strip_tags($str);
    if (mb_strlen($buff) > $n_chars) {
        $cut_index = mb_strpos($buff, ' ', $n_chars);
        $buff = mb_substr($buff, 0, ($cut_index === false ? $n_chars : $cut_index + 1), "UTF-8") . $crop_str;
    }
    return $buff;
}
Waqleh
źródło
0
$yourString = "bla blaaa bla blllla bla bla";
$out = "";
if(strlen($yourString) > 22) {
    while(strlen($yourString) > 22) {
        $pos = strrpos($yourString, " ");
        if($pos !== false && $pos <= 22) {
            $out = substr($yourString,0,$pos);
            break;
        } else {
            $yourString = substr($yourString,0,$pos);
            continue;
        }
    }
} else {
    $out = $yourString;
}
echo "Output String: ".$out;
Jaykishan
źródło
0

Jeśli nie ma sztywnych wymagań dotyczących długości obciętego łańcucha, można go użyć do obcięcia i zapobiegania wycięciu ostatniego słowa:

$text = "Knowledge is a natural right of every human being of which no one
has the right to deprive him or her under any pretext, except in a case where a
person does something which deprives him or her of that right. It is mere
stupidity to leave its benefits to certain individuals and teams who monopolize
these while the masses provide the facilities and pay the expenses for the
establishment of public sports.";

// we don't want new lines in our preview
$text_only_spaces = preg_replace('/\s+/', ' ', $text);

// truncates the text
$text_truncated = mb_substr($text_only_spaces, 0, mb_strpos($text_only_spaces, " ", 50));

// prevents last word truncation
$preview = trim(mb_substr($text_truncated, 0, mb_strrpos($text_truncated, " ")));

W takim przypadku $previewbędzie "Knowledge is a natural right of every human being".

Przykład kodu na żywo: http://sandbox.onlinephpfunctions.com/code/25484a8b687d1f5ad93f62082b6379662a6b4713

jim_kastrin
źródło