Cara cerdas untuk memotong string panjang


187

Adakah yang punya solusi / pustaka yang lebih canggih untuk memotong string dengan JavaScript dan meletakkan elipsis di bagian akhir, daripada yang jelas:

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

5
Apa yang Anda maksud dengan "lebih canggih"? Fungsi yang memperhitungkan batasan kata?
Residuum

2
Dan tidak terpotong di tengah tag HTML.
Sz.

Jawaban:


366

Intinya, Anda memeriksa panjang string yang diberikan. Jika lebih panjang dari panjang yang diberikan n, klip panjangnya n( substratau slice) dan tambahkan entitas html …(...) ke string yang terpotong.

Metode seperti itu terlihat seperti

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

Jika dengan 'lebih canggih' yang Anda maksud memotong pada batas kata terakhir dari string maka Anda perlu pemeriksaan tambahan. Pertama, Anda klip string ke panjang yang diinginkan, selanjutnya Anda klip hasilnya ke batas kata terakhir

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;";
};

Anda dapat memperluas Stringprototipe asli dengan fungsi Anda. Dalam hal ini strparameter harus dihapus dan strdalam fungsi harus diganti dengan 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;";
};

Lebih banyak pengembang dogmatis mungkin akan sangat mendukung Anda (" Jangan memodifikasi objek yang tidak Anda miliki ". Namun saya tidak keberatan).

Pendekatan tanpa memperluas Stringprototipe adalah dengan membuat objek pembantu Anda sendiri, berisi string (panjang) yang Anda berikan dan metode sebelumnya untuk memotongnya. Itulah yang dilakukan cuplikan di bawah.

Akhirnya, Anda dapat menggunakan css hanya untuk memotong string panjang di node HTML. Ini memberi Anda lebih sedikit kontrol, tetapi mungkin solusi yang layak.


5
Harus juga mempertimbangkan memiliki batas "keras" dan "lunak", seperti, misalnya, jika string lebih panjang dari 500 karakter, potong menjadi 400. Ini mungkin berguna, ketika pengguna ingin melihat seluruh teks dan mengklik beberapa tautan untuk itu. Jika, sebagai hasilnya, Anda hanya memuat 1 atau 2 karakter lagi, itu akan terlihat sangat jelek.
Maxim Sloyko

2
Parameter kedua substradalah panjang sehingga harus substr(0,n)membatasi ke nkarakter pertama .
JohnnyHK

10
Jangan memodifikasi objek yang bukan milik Anda. nczonline.net/blog/2010/03/02/...
Charlie Kilian

5
Satu hal yang mungkin Anda pertimbangkan adalah mengganti &hellip;dengan ellipsis aktual ( ...) pada contoh kode Anda. Jika Anda mencoba menggunakan ini untuk berinteraksi dengan API, Anda akan menginginkan entitas non-HTML di sana.
AlbertEngelB

1
@ RunJeppesen Anda benar. Menyesuaikan metode. Untuk pembelaan saya: jawabannya tanggal 7 tahun yang lalu;)
KooiInc

62

Perhatikan bahwa ini hanya perlu dilakukan untuk Firefox.

Semua browser lain mendukung solusi CSS (lihat tabel dukungan ):

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 */
}

Ironisnya adalah saya mendapatkan potongan kode dari Mozilla MDC.


1
mattsnider.com/css/css-string-truncation-with-ellipsis untuk membuatnya bekerja dengan FF juga.
Neal

Wow ini adalah solusi sempurna untuk Safari seluler. Terima kasih!
samvermette

9
Pendekatan CSS yang sangat bagus. Mungkin ada catatan, bahwa ini hanya berfungsi dengan satu baris teks (sebagaimana dimaksud oleh white-space: nowrap;). Ketika datang ke lebih dari satu baris Anda terjebak dengan JavaScript.
insertusernamehere

Ini juga hanya berfungsi untuk seluruh elemen. Jika Anda ingin memotong bagian dari string, tanpa membungkus bit yang ingin Anda potong dalam rentang atau elemen html lainnya, ini tidak akan berfungsi misalnya:Your picture ('some very long picture filename truncated...') has been uploaded.
Chris

1
OP meminta secara khusus untuk solusi javascript
vsync

24

Ada alasan yang sah bahwa orang mungkin ingin melakukan ini dalam JavaScript alih-alih CSS.

Untuk memotong hingga 8 karakter (termasuk elipsis) dalam JavaScript:

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

atau

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

Jika Anda menghitung ellipsis, ini akan menjadi 9 karakter. Jika Anda perlu untuk menjadi 8 setelah pemotongan, menggunakan .replace(/^(.{7}).{2,}/, "$1…");bukan
OKKU

longdan shortdicadangkan sebagai kata kunci di masa mendatang dengan spesifikasi ECMAScript yang lebih lama (ECMAScript 1 hingga 3). Lihat MDN: Kata kunci yang disimpan di masa mendatang dalam standar yang lebih lama
Ricardo


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

Entah bagaimana kode di atas tidak berfungsi untuk beberapa jenis teks yang disalin atau disalin dalam aplikasi vuejs. Jadi saya menggunakan trashate lodash dan sekarang berfungsi dengan baik.

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

jawaban modern yang bagus!
ykonda

Saya ingin tahu apa teksnya. Apakah menggunakan karakter non-Latin?
Adam Leggett

Itu hanya lorem ipsum
Afraz Ahmad

7

Inilah solusi saya, yang memiliki beberapa peningkatan dibandingkan saran lainnya:

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;"

Itu:

  • Potong di spasi pertama setelah 25 karakter
  • Memperluas objek String JavaScript, sehingga dapat digunakan pada (dan dirantai ke) string apa pun.
  • Akan memangkas string jika pemotongan menghasilkan ruang tambahan;
  • Akan menambahkan entitas hellip unicode (ellipsis) jika string terpotong lebih dari 25 karakter

7

Fungsi terbaik yang saya temukan. Kredit untuk elipsis teks .

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;
}

Contoh :

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"

5

Semua browser modern sekarang mendukung solusi CSS sederhana untuk secara otomatis menambahkan elipsis jika satu baris teks melebihi lebar yang tersedia:

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

(Perhatikan bahwa ini membutuhkan lebar elemen untuk dibatasi dalam beberapa cara agar memiliki efek apa pun.)

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

Perlu dicatat bahwa pendekatan ini tidak membatasi berdasarkan jumlah karakter. Ini juga tidak berfungsi jika Anda perlu mengizinkan beberapa baris teks.


2
Ini hanya berguna untuk kalimat satu baris, tidak ada cara (sejauh yang saya tahu) untuk melakukan contoh multi-baris melalui CSS.
Hooman Askari

Apakah ada cara untuk membuat ini melakukan elipsis di sebelah kiri dan bukan di kanan?
GreenAsJade

1
@GreenAsJade Saya yakin Anda bisa mencapainya dengan menggunakan text-direction: rtldan text-align: left. Lihat davidwalsh.name/css-ellipsis-left
Sean the Bean

4

Sebagian besar kerangka kerja Javascript modern ( JQuery , Prototype , dll ...) memiliki fungsi utilitas yang ditempel pada String yang menangani ini.

Berikut ini contoh dalam Prototipe:

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

Ini sepertinya salah satu fungsi yang Anda ingin orang lain atasi / pelihara. Saya membiarkan kerangka mengatasinya, daripada menulis lebih banyak kode.


8
Saya tidak berpikir jQuery memiliki sesuatu untuk ini.
alex

2
Underscore.js tidak - _ ('Hello world'). Truncate (5) => 'Hello ...' _ ('Hello'). Truncate (10) => 'Halo'
JayCrossler

3
Pure Underscore tampaknya juga tidak memiliki truncate()- Anda mungkin memerlukan ekstensi seperti underscore.string .
martin

2
Ini jawaban yang benar-benar tepat. Saya tidak tahu tentang garis bawah, tetapi lodash memiliki _.truncyang melakukan ini.
leftclickben

2
Saya pikir jawaban yang tepat adalah dengan menggunakan lodash.trunc atau underscore.string.truncate.
ooolala

2

Mungkin saya melewatkan contoh di mana seseorang menangani nol, tetapi 3 jawaban TOP tidak bekerja untuk saya ketika saya punya nol (Tentu saya menyadari bahwa penanganan kesalahan ada dan jutaan hal lainnya BUKAN tanggung jawab orang yang menjawab pertanyaan, tetapi karena Saya telah menggunakan fungsi yang ada bersama dengan salah satu jawaban elipsis pemotongan yang sangat baik saya pikir saya akan menyediakannya untuk orang lain.

misalnya

javascript:

news.comments

menggunakan fungsi pemotongan

news.comments.trunc(20, true);

Namun, pada news.comments menjadi nol, ini akan "pecah"

Terakhir

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

trunc function courtesy of 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_;
 };

Null checker sederhana saya (memeriksa hal "null" literal juga (tangkapan ini tidak terdefinisi, "", null, "null", dll.)

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

Berikut ini adalah versi yang dimodifikasi - hindari penggunaan prototipe, menyertakan fungsi null checking, dan memiliki beberapa pengujian / penggunaan demo. codepen.io/mahemoff/pen/LGEdzy
mahemoff

Apakah Anda menemukan prototipe bermasalah? Hanya ingin tahu
Tom Stickel 8-15

Alasan untuk fungsi pemeriksaan nol terpisah saya adalah bahwa ia akan benar-benar memeriksa null, tidak terdefinisi, NaN, string kosong (""), 0, false dan "null" Tapi secara keseluruhan saya suka fx Anda
Tom Stickel

1
Ya, ini masalah opini dan konteks penggunaan, tetapi prototipe menjadi jelek ketika Anda bekerja dengan perpustakaan lain karena mereka mungkin juga menimpa hal yang sama. (Atau dalam kasus yang jarang terjadi, fungsi dengan nama yang sama mungkin kemudian diperkenalkan sebagai fitur bahasa standar.)
mahemoff

Ya, saya setuju dengan Anda
Tom Stickel 815

2

Terkadang nama file diberi nomor, di mana indeksnya mungkin di awal atau di akhir. Jadi saya ingin mempersingkat dari pusat string:

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);
}

Ketahuilah bahwa saya menggunakan karakter isian di sini dengan lebih dari 1 byte dalam UTF-8.



1

Saya meningkatkan solusi Kooilnc. Solusi kompak yang sangat bagus. Ada satu kasus tepi kecil yang ingin saya atasi. Jika seseorang memasukkan urutan karakter yang sangat panjang untuk alasan apa pun, itu tidak akan terpotong:

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

Dengan Googling cepat saya menemukan ini ... Apakah itu bekerja untuk Anda?

/**
 * 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-overflow: ellipsis adalah properti yang Anda butuhkan. Dengan ini dan limpahan: disembunyikan dengan lebar tertentu, semua yang melampaui yang akan mendapatkan efek tiga periode di akhir ... Jangan lupa untuk menambahkan spasi putih: nowrap atau teks akan diletakkan dalam beberapa baris.

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

1
Brevity dapat diterima, tetapi penjelasan yang lebih lengkap lebih baik.
Armali

mwilcox dan Sean the Bean sudah memposting solusi ini.
Andrew Myers

1
Hanya dapat digunakan untuk teks satu baris
Vally Pepyako

Teks-overflow: ellipsis sempurna !!
zardilior

0

Jawaban c_harm menurut saya adalah yang terbaik. Harap dicatat bahwa jika Anda ingin menggunakannya

"My string".truncate(n)

Anda harus menggunakan konstruktor objek regexp daripada literal. Anda juga harus melarikan diri \Sketika mengubahnya.

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;';
    };

Setiap mendengar komentar dan penamaan variabel yang tepat?
sepeda

@ sepeda kode disalin dan dimodifikasi dari jawaban lain di atas, tidak perlu begitu kasar dan snarky.
Matt Fletcher

0

Gunakan kode berikut

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

0

Memperbaiki solusi Kooilnc:

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

Ini mengembalikan nilai string daripada objek String jika tidak perlu dipotong.


Ini tidak memberikan jawaban untuk pertanyaan itu. Untuk mengkritik atau meminta klarifikasi dari seorang penulis, tinggalkan komentar di bawah posting mereka - Anda selalu dapat mengomentari posting Anda sendiri, dan begitu Anda memiliki reputasi yang cukup, Anda akan dapat mengomentari setiap posting .
Spencer Wieczorek

Ah saya melihat perbedaannya sekarang. Terima kasih untuk referensi. Saya memang ingin memberikan komentar dengan harapan bahwa @Kooilnc akan melihatnya, dan mungkin mengedit jawaban yang diterima jika dia setuju, tetapi tidak memiliki reputasi.
qwales1

0

Saya baru-baru ini harus melakukan ini dan berakhir dengan:

/**
 * 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, '...');
}

Terasa bagus dan bersih bagiku :)


1
Itu bisa membuat string 3 karakter yang dihasilkan lebih lama dari batas.
Hauke

0

Saya suka menggunakan .slice () Argumen pertama adalah indeks awal dan yang kedua adalah indeks akhir. Segala sesuatu di antaranya adalah apa yang Anda dapatkan kembali.

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

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

0

Somewhere Smart: 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

Fungsi ini melakukan bagian terpotong dan kata-kata bagian juga. (Ex: Mother into Moth ...)

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

pemakaian:

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

keluaran:

ini adalah ...

12345 ...

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.