Intelligente Methode zum Abschneiden langer Zeichenfolgen


183

Hat jemand eine ausgefeiltere Lösung / Bibliothek zum Abschneiden von Zeichenfolgen mit JavaScript und zum Setzen einer Ellipse am Ende als die offensichtliche:

if (string.length > 25) {
  string = string.substring(0, 24) + "...";
}

5
Was meinst du mit "anspruchsvoller"? Funktionen, die Wortgrenzen berücksichtigen?
Residuum

1
Und nicht mitten in HTML-Tags abschneiden.
Gr.

Antworten:


362

Im Wesentlichen überprüfen Sie die Länge der angegebenen Zeichenfolge. Wenn es länger als eine bestimmte Länge ist n, schneiden Sie es auf Länge n( substroder slice) und fügen Sie eine HTML-Entität hinzu… der abgeschnittenen Zeichenfolge (…) hinzu.

Eine solche Methode sieht aus

function truncate(str, n){
  return (str.length > n) ? str.substr(0, n-1) + '…' : str;
};

Wenn Sie mit "anspruchsvoller" das Abschneiden an der letzten Wortgrenze einer Zeichenfolge meinen, benötigen Sie eine zusätzliche Prüfung. Zuerst schneiden Sie die Zeichenfolge auf die gewünschte Länge, dann schneiden Sie das Ergebnis bis zur letzten Wortgrenze

function truncate( str, n, useWordBoundary ){
  if (str.length <= n) { return str; }
  const subString = str.substr(0, n-1); // the original check
  return (useWordBoundary 
    ? subString.substr(0, subString.lastIndexOf(" ")) 
    : subString) + "&hellip;";
};

Sie können den nativen StringPrototyp mit Ihrer Funktion erweitern. In diesem Fall sollte der strParameter entfernt und strinnerhalb der Funktion ersetzt werden durch this:

String.prototype.truncate = String.prototype.truncate || 
function ( n, useWordBoundary ){
  if (this.length <= n) { return this; }
  const subString = this.substr(0, n-1); // the original check
  return (useWordBoundary 
    ? subString.substr(0, subString.lastIndexOf(" ")) 
    : subString) + "&hellip;";
};

Dogmatischere Entwickler können Sie stark darüber kapitulieren (" Ändern Sie keine Objekte, die Sie nicht besitzen ". Es würde mir jedoch nichts ausmachen).

Ein Ansatz ohne Erweiterung des StringPrototyps besteht darin, ein eigenes Hilfsobjekt zu erstellen, das die von Ihnen angegebene (lange) Zeichenfolge und die zuvor erwähnte Methode zum Abschneiden enthält. Das macht der folgende Ausschnitt.

Schließlich können Sie CSS nur verwenden, um lange Zeichenfolgen in HTML-Knoten abzuschneiden. Es gibt Ihnen weniger Kontrolle, kann aber durchaus eine praktikable Lösung sein.


5
Sollte auch in Betracht gezogen werden, "harte" und "weiche" Grenzwerte festzulegen, z. B. wenn die Zeichenfolge länger als 500 Zeichen ist, kürzen Sie sie auf 400. Dies kann nützlich sein, wenn der Benutzer den gesamten Text sehen und auf einen Link klicken möchte dafür. Wenn Sie infolgedessen nur 1 oder 2 Zeichen mehr laden, sieht es wirklich hässlich aus.
Maxim Sloyko

2
Der zweite Parameter substrist eine Länge, daher sollte er substr(0,n)stattdessen auf die ersten nZeichen beschränkt werden.
JohnnyHK

10
Ändern Sie keine Objekte, die Sie nicht besitzen. nczonline.net/blog/2010/03/02/…
Charlie Kilian

5
Eine Sache, die Sie in Betracht ziehen könnten, ist das Ersetzen des &hellip;durch das tatsächliche Auslassungszeichen ( ...) in Ihrem Codebeispiel. Wenn Sie versuchen, dies für die Interaktion mit APIs zu verwenden, möchten Sie die Nicht-HTML-Entität dort haben.
AlbertEngelB

1
@ RunJeppesen du hast recht. Die Methoden wurden angepasst. Zu meiner Verteidigung: Die Antwort stammt aus 7 Jahren;)
KooiInc

62

Beachten Sie, dass dies nur für Firefox durchgeführt werden muss.

Alle anderen Browser unterstützen eine CSS-Lösung (siehe Support-Tabelle ):

p {
    white-space: nowrap;
    width: 100%;                   /* IE6 needs any width */
    overflow: hidden;              /* "overflow" value must be different from  visible"*/ 
    -o-text-overflow: ellipsis;    /* Opera < 11*/
    text-overflow:    ellipsis;    /* IE, Safari (WebKit), Opera >= 11, FF > 6 */
}

Die Ironie ist, dass ich diesen Code-Ausschnitt von Mozilla MDC bekommen habe.


1
mattsnider.com/css/css-string-truncation-with-ellipsis , damit es auch mit FF funktioniert.
Neal

Wow, das ist eine perfekte Lösung für mobile Safari. Danke dir!
Samvermette

9
Sehr guter CSS-Ansatz. Möglicherweise wird darauf hingewiesen, dass dies nur mit einer einzelnen Textzeile funktioniert (wie von beabsichtigt white-space: nowrap;). Wenn es um mehr als eine Zeile geht, bleibt JavaScript hängen.
Insertusernamehere

Es funktioniert auch nur für das gesamte Element. Wenn Sie einen Teil einer Zeichenfolge abschneiden möchten, ohne das Bit, das Sie abschneiden möchten, in einen Bereich oder ein anderes HTML-Element einzuschließen, funktioniert dies nicht, z. B.:Your picture ('some very long picture filename truncated...') has been uploaded.
Chris,

1
OP fragte speziell nach einer Javascript-Lösung
vsync

24

Es gibt triftige Gründe, warum Benutzer dies in JavaScript anstelle von CSS tun möchten.

So schneiden Sie in JavaScript 8 Zeichen (einschließlich Auslassungspunkte) ab:

short = long.replace(/(.{7})..+/, "$1&hellip;");

oder

short = long.replace(/(.{7})..+/, "$1…");

Wenn Sie die Auslassungspunkte zählen, sind dies 9 Zeichen. Wenn es nach dem Abschneiden 8 sein muss, verwenden Sie .replace(/^(.{7}).{2,}/, "$1…");stattdessen
Okku

longund shortwerden von älteren ECMAScript-Spezifikationen (ECMAScript 1 bis 3) als zukünftige Schlüsselwörter reserviert. Siehe MDN: Zukünftig reservierte Schlüsselwörter in älteren Standards
Ricardo


7

Hier ist meine Lösung, die einige Verbesserungen gegenüber anderen Vorschlägen aufweist:

String.prototype.truncate = function(){
    var re = this.match(/^.{0,25}[\S]*/);
    var l = re[0].length;
    var re = re[0].replace(/\s$/,'');
    if(l < this.length)
        re = re + "&hellip;";
    return re;
}

// "This is a short string".truncate();
"This is a short string"

// "Thisstringismuchlongerthan25characters".truncate();
"Thisstringismuchlongerthan25characters"

// "This string is much longer than 25 characters and has spaces".truncate();
"This string is much longer&hellip;"

Es:

  • Wird nach 25 Zeichen im ersten Leerzeichen abgeschnitten
  • Erweitert das JavaScript-Zeichenfolgenobjekt, sodass es für jede Zeichenfolge verwendet (und mit dieser verkettet) werden kann.
  • Trimmt die Zeichenfolge, wenn das Abschneiden zu einem nachgestellten Leerzeichen führt.
  • Fügt die Unicode-Hellip-Entität (Auslassungspunkte) hinzu, wenn die abgeschnittene Zeichenfolge länger als 25 Zeichen ist

7

Beste Funktion, die ich gefunden habe. Gutschrift auf Text-Auslassungspunkten .

function textEllipsis(str, maxLength, { side = "end", ellipsis = "..." } = {}) {
  if (str.length > maxLength) {
    switch (side) {
      case "start":
        return ellipsis + str.slice(-(maxLength - ellipsis.length));
      case "end":
      default:
        return str.slice(0, maxLength - ellipsis.length) + ellipsis;
    }
  }
  return str;
}

Beispiele :

var short = textEllipsis('a very long text', 10);
console.log(short);
// "a very ..."

var short = textEllipsis('a very long text', 10, { side: 'start' });
console.log(short);
// "...ng text"

var short = textEllipsis('a very long text', 10, { textEllipsis: ' END' });
console.log(short);
// "a very END"

7
('long text to be truncated').replace(/(.{250})..+/, "$1…");

Irgendwie funktionierte der obige Code nicht für eine Art kopierten oder geschriebenen Text in der vuejs App. Also habe ich lodash truncate verwendet und es funktioniert jetzt gut.

_.truncate('long text to be truncated', { 'length': 250, 'separator': ' '});

schöne moderne Antwort!
Ykonda

Ich wäre gespannt, was der Text ist. Wurden nicht-lateinische Zeichen verwendet?
Adam Leggett

Es war nur ein Lorem Ipsum
Afraz Ahmad

5

Alle modernen Browser unterstützen jetzt eine einfache CSS-Lösung zum automatischen Hinzufügen von Auslassungspunkten, wenn eine Textzeile die verfügbare Breite überschreitet:

p {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

(Beachten Sie, dass hierfür die Breite des Elements in irgendeiner Weise begrenzt werden muss, um einen Effekt zu erzielen.)

Basierend auf https://css-tricks.com/snippets/css/truncate-string-with-ellipsis/ .

Es ist zu beachten, dass dieser Ansatz nicht auf der Anzahl der Zeichen basiert. Es funktioniert auch nicht , wenn Sie mehrere Textzeilen zulassen müssen.


2
Dies ist nur für einzeilige Sätze nützlich. Soweit ich weiß, gibt es keine Möglichkeit, ein mehrzeiliges Beispiel über CSS zu erstellen.
Hooman Askari

Gibt es eine Möglichkeit, dies dazu zu bringen, die Auslassungspunkte links statt rechts zu machen?
GreenAsJade

1
@ GreenAsJade Ich glaube, Sie können dies mit text-direction: rtlund erreichen text-align: left. Siehe davidwalsh.name/css-ellipsis-left
Sean the Bean

4

Die meisten modernen Javascript - Frameworks ( JQuery , Prototype , etc. ...) haben eine Nutzenfunktion String gehefteten auf die Griffe dieser.

Hier ist ein Beispiel in Prototype:

'Some random text'.truncate(10);
// -> 'Some ra...'

Dies scheint eine der Funktionen zu sein, mit denen sich jemand anderes befassen / die Sie warten sollen. Ich würde das Framework damit umgehen lassen, anstatt mehr Code zu schreiben.


8
Ich glaube nicht, dass jQuery etwas dafür hat.
Alex

2
Underscore.js tut - _ ('Hallo Welt'). Truncate (5) => 'Hello ...' _ ('Hello'). Truncate (10) => 'Hello'
JayCrossler

3
Pure Underscore scheint es auch nicht zu haben truncate()- möglicherweise benötigen Sie eine Erweiterung wie underscore.string .
Martin

2
Dies ist die richtige Antwort. Ich weiß nichts über Unterstriche, aber lodash hat _.truncgenau das.
leftclickben

2
Ich denke, die richtige Antwort ist, lodash.trunc oder underscore.string.truncate zu verwenden.
Ooolala

2

Vielleicht habe ich ein Beispiel verpasst, in dem jemand mit Nullen umgeht, aber 3 TOP-Antworten haben bei mir nicht funktioniert, als ich Nullen hatte (Sicher ist mir klar, dass die Fehlerbehandlung und Millionen anderer Dinge NICHT in der Verantwortung der Person liegen, die die Frage beantwortet, sondern seitdem Ich hatte eine vorhandene Funktion zusammen mit einer der hervorragenden Antworten auf Kürzungsellipsen verwendet, von denen ich dachte, ich würde sie für andere bereitstellen.

z.B

Javascript:

news.comments

mit Kürzungsfunktion

news.comments.trunc(20, true);

Wenn news.comments jedoch null ist, würde dies "brechen".

Finale

checkNull(news.comments).trunc(20, true) 

Trunc-Funktion mit freundlicher Genehmigung von KooiInc

String.prototype.trunc =
 function (n, useWordBoundary) {
     console.log(this);
     var isTooLong = this.length > n,
         s_ = isTooLong ? this.substr(0, n - 1) : this;
     s_ = (useWordBoundary && isTooLong) ? s_.substr(0, s_.lastIndexOf(' ')) : s_;
     return isTooLong ? s_ + '&hellip;' : s_;
 };

Mein einfacher Null-Checker (sucht auch nach dem wörtlichen "Null" -Ding (dies fängt undefinierte, "", null, "null" usw. ab).

  function checkNull(val) {
      if (val) {
          if (val === "null") {
              return "";
          } else {
              return val;
          }
      } else {
          return "";
      }
  }

Hier ist eine modifizierte Version - vermeidet die Verwendung von Prototypen, beinhaltet die Nullprüfung in der Funktion und verwendet einige Tests / Demos. codepen.io/mahemoff/pen/LGEdzy
mahemoff

Finden Sie den Prototyp problematisch? Nur neugierig
Tom Stickel

Der Grund für meine separate Null-Check-Funktion ist, dass sie tatsächlich nach Null, undefiniert, NaN, leerer String (""), 0, false und "null" sucht. Aber insgesamt mag ich Ihren FX
Tom Stickel

1
Ja, es ist eine Frage der Meinung und des Verwendungskontexts, aber der Prototyp wird hässlich, wenn Sie mit anderen Bibliotheken arbeiten, da diese möglicherweise auch dasselbe überschreiben. (Oder in seltenen Fällen kann eine gleichnamige Funktion später als Standardsprache eingeführt werden.)
Mahemoff

Ja, ich stimme Ihnen zu
Tom Stickel

2

Manchmal sind Dateinamen nummeriert, wobei der Index am Anfang oder am Ende stehen kann. Also wollte ich von der Mitte der Saite aus kürzen:

function stringTruncateFromCenter(str, maxLength) {
    const midChar = "…";      // character to insert into the center of the result
    var left, right;

    if (str.length <= maxLength) return str;

    // length of beginning part      
    left = Math.ceil(maxLength / 2);

    // start index of ending part   
    right = str.length - Math.floor(maxLength / 2) + 1;   

    return str.substr(0, left) + midChar + str.substring(right);
}

Beachten Sie, dass ich hier in UTF-8 ein Füllzeichen mit mehr als 1 Byte verwendet habe.



1

Ich habe die Lösung von Kooilnc positiv bewertet. Wirklich schöne kompakte Lösung. Es gibt einen kleinen Randfall, den ich ansprechen möchte. Wenn jemand aus irgendeinem Grund eine wirklich lange Zeichenfolge eingibt, wird diese nicht abgeschnitten:

function truncate(str, n, useWordBoundary) {
    var singular, tooLong = str.length > n;
    useWordBoundary = useWordBoundary || true;

    // Edge case where someone enters a ridiculously long string.
    str = tooLong ? str.substr(0, n-1) : str;

    singular = (str.search(/\s/) === -1) ? true : false;
    if(!singular) {
      str = useWordBoundary && tooLong ? str.substr(0, str.lastIndexOf(' ')) : str;
    }

    return  tooLong ? str + '&hellip;' : str;
}

1

Mit einem schnell gefunden googeln ich dieses ... für Sie tut das?

/**
 * Truncate a string to the given length, breaking at word boundaries and adding an elipsis
 * @param string str String to be truncated
 * @param integer limit Max length of the string
 * @return string
 */
var truncate = function (str, limit) {
    var bits, i;
    if (STR !== typeof str) {
        return '';
    }
    bits = str.split('');
    if (bits.length > limit) {
        for (i = bits.length - 1; i > -1; --i) {
            if (i > limit) {
                bits.length = i;
            }
            else if (' ' === bits[i]) {
                bits.length = i;
                break;
            }
        }
        bits.push('...');
    }
    return bits.join('');
};
// END: truncate

1

Textüberlauf: Auslassungspunkte sind die Eigenschaft, die Sie benötigen. Mit diesem und einem Überlauf: versteckt mit einer bestimmten Breite, alles, was den Drei-Perioden-Effekt am Ende übertrifft ... Vergessen Sie nicht, Leerzeichen hinzuzufügen: nowrap oder der Text wird in mehrere Zeilen eingefügt.

.wrap{
  text-overflow: ellipsis
  white-space: nowrap;
  overflow: hidden;
  width:"your desired width";
}
<p class="wrap">The string to be cut</p>

1
Kürze ist akzeptabel, aber ausführlichere Erklärungen sind besser.
Armali

mwilcox und Sean the Bean haben diese Lösung bereits veröffentlicht.
Andrew Myers

1
Kann nur für einzeiligen Text verwendet werden
Vally Pepyako

Der Textüberlauf: Auslassungspunkte sind perfekt !!
Zardilior

0

Die Antwort von c_harm ist meiner Meinung nach die beste. Bitte beachten Sie, dass, wenn Sie verwenden möchten

"My string".truncate(n)

Sie müssen einen Regexp-Objektkonstruktor anstelle eines Literal verwenden. Außerdem müssen Sie \Sbeim Konvertieren dem entkommen .

String.prototype.truncate =
    function(n){
        var p  = new RegExp("^.{0," + n + "}[\\S]*", 'g');
        var re = this.match(p);
        var l  = re[0].length;
        var re = re[0].replace(/\s$/,'');

        if (l < this.length) return re + '&hellip;';
    };

Jeder von Kommentaren und der richtigen Benennung von Variablen gehört?
Fahrrad

@bicycle Der Code wird aus einer anderen Antwort oben kopiert und geändert. Sie müssen nicht so unhöflich und bissig sein.
Matt Fletcher

0

Verwenden Sie den folgenden Code

 function trancateTitle (title) {
    var length = 10;
    if (title.length > length) {
       title = title.substring(0, length)+'...';
    }
    return title;
}

0

Korrektur der Kooilnc-Lösung:

String.prototype.trunc = String.prototype.trunc ||
  function(n){
      return this.length>n ? this.substr(0,n-1)+'&hellip;' : this.toString();
  };

Dies gibt den Zeichenfolgenwert anstelle des Zeichenfolgenobjekts zurück, wenn es nicht abgeschnitten werden muss.


Dies gibt keine Antwort auf die Frage. Um einen Autor zu kritisieren oder um Klarstellung zu bitten, hinterlassen Sie einen Kommentar unter seinem Beitrag. Sie können jederzeit Ihre eigenen Beiträge kommentieren. Sobald Sie einen ausreichenden Ruf haben, können Sie jeden Beitrag kommentieren .
Spencer Wieczorek

Ah, ich sehe jetzt den Unterschied. Danke für die Referenzen. Ich wollte einen Kommentar mit der Hoffnung hinterlassen, dass @Kooilnc ihn sehen würde, und möglicherweise die akzeptierte Antwort bearbeiten, wenn er oder sie zustimmte, aber nicht den Ruf hatte.
Qwales1

0

Ich musste dies kürzlich tun und endete mit:

/**
 * Truncate a string over a given length and add ellipsis if necessary
 * @param {string} str - string to be truncated
 * @param {integer} limit - max length of the string before truncating
 * @return {string} truncated string
 */
function truncate(str, limit) {
    return (str.length < limit) ? str : str.substring(0, limit).replace(/\w{3}$/gi, '...');
}

Fühlt sich gut und sauber für mich an :)


1
Dies könnte dazu führen, dass die resultierende Zeichenfolge 3 Zeichen länger als das Limit ist.
Hauke

0

Ich benutze gerne .slice () Das erste Argument ist der Startindex und das zweite ist der Endindex. Alles dazwischen bekommen Sie zurück.

var long = "hello there! Good day to ya."
// hello there! Good day to ya.

var short  = long.slice(0, 5)
// hello

0

Irgendwo klug: D.

//My Huge Huge String
    let tooHugeToHandle = `It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like).`
    
//Trim Max Length
 const maxValue = 50
// The barber.
 const TrimMyString = (string, maxLength, start = 0) => {
//Note - `start` is if I want to start after some point of the string
    	if (string.length > maxLength) {
    	let trimmedString = string.substr(start, maxLength)
    	 return (
    	   trimmedString.substr(
    	   start,
    	   Math.min(trimmedString.length,   trimmedString.lastIndexOf(' '))
           ) + ' ...'
         )
       }
    return string
}

console.log(TrimMyString(tooHugeToHandle, maxValue))


-1

Diese Funktion übernimmt auch das Abschneiden von Leerzeichen und Wörtern (z. B. Mutter in Motte ...)

String.prototype.truc= function (length) {
        return this.length>length ? this.substring(0, length) + '&hellip;' : this;
};

Verwendung:

"this is long length text".trunc(10);
"1234567890".trunc(5);

Ausgabe:

das ist lo ...

12345 ...

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.