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) + "...";
}
naltatis
sumber
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.

KooiInc
sumber
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.

mwilcox
sumber
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…");
Adam Leggett
sumber
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
23

Gunakan kedua tempat pemotongan itu

_.truncate('hi-diddly-ho there, neighborino');
// → 'hi-diddly-ho there, neighbo…'

atau garis bawah . tringate .

_('Hello world').truncate(5); => 'Hello...'
ooolala
sumber
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': ' '});
Afraz Ahmad
sumber
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

sumber
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"
Jeff Hernandez
sumber
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.

Sean the Bean
sumber
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.

Jim Fiorato
sumber
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 "";
      }
  }
Tom Stickel
sumber
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.

Hauke
sumber
1

Anda dapat menggunakan fungsi Ext.util.Format.ellipsis jika Anda menggunakan Ext.js.

danrecardoso
sumber
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;
}
backdesk
sumber
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
Manrico Corazzi
sumber
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>
vijay kanaujia
sumber
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;';
    };
Matt Fletcher
sumber
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;
}
Chathurka
sumber
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.

qwales1
sumber
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 :)

John Doherty
sumber
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
Eric Wallen
sumber
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))

Satyam Pathak
sumber
-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 ...

Elshan
sumber