Сократите строку, не обрезая слова в JavaScript - PullRequest
78 голосов
/ 28 марта 2011

Я не очень хорош в манипулировании строками в JavaScript, и мне было интересно, как вы будете сокращать строку, не обрезая слова. Я знаю, как использовать подстроку, но не indexOf или что-то действительно хорошее.

Скажем, у меня была следующая строка:

text = "this is a long string I cant display"

Я хочу сократить его до 10 символов, но если оно не заканчивается пробелом, допиши слово. Я не хочу, чтобы строковая переменная выглядела так:

"это длинная строка, которую я не могу найти"

Я хочу, чтобы оно заканчивало слово, пока не будет пробел.

Ответы [ 20 ]

154 голосов
/ 28 марта 2011

Если я правильно понимаю, вы хотите сократить строку до определенной длины (например, сократить "The quick brown fox jumps over the lazy dog", скажем, до 6 символов, не обрезая ни одного слова).можно попробовать что-то вроде следующего:

var yourString = "The quick brown fox jumps over the lazy dog"; //replace with your string.
var maxLength = 6 // maximum number of characters to extract

//trim the string to the maximum length
var trimmedString = yourString.substr(0, maxLength);

//re-trim if we are in the middle of a word
trimmedString = trimmedString.substr(0, Math.min(trimmedString.length, trimmedString.lastIndexOf(" ")))
85 голосов
/ 28 марта 2011

Есть много способов сделать это, но регулярное выражение является полезным однострочным методом:

"this is a longish string of text".replace(/^(.{11}[^\s]*).*/, "$1"); 
//"this is a longish"

Это выражение возвращает первые 11 (любые) символы плюс любые последующие непробельные символы.

Пример сценария:

<pre>
<script>
var t = "this is a longish string of text";

document.write("1:   " + t.replace(/^(.{1}[^\s]*).*/, "$1") + "\n");
document.write("2:   " + t.replace(/^(.{2}[^\s]*).*/, "$1") + "\n");
document.write("5:   " + t.replace(/^(.{5}[^\s]*).*/, "$1") + "\n");
document.write("11:  " + t.replace(/^(.{11}[^\s]*).*/, "$1") + "\n");
document.write("20:  " + t.replace(/^(.{20}[^\s]*).*/, "$1") + "\n");
document.write("100: " + t.replace(/^(.{100}[^\s]*).*/, "$1") + "\n");
</script>

Выход:

1:   this
2:   this
5:   this is
11:  this is a longish
20:  this is a longish string
100: this is a longish string of text
50 голосов
/ 02 ноября 2016

Я отчасти удивлен, что для такой простой проблемы, как эта, так много ответов, которые трудно прочитать, и некоторые, в том числе выбранный, не работают.

Обычно я хочу, чтобы результирующая строка была не более maxLen символов. Я также использую эту же функцию, чтобы сократить количество слагов в URL.

str.lastIndexOf(searchValue[, fromIndex]) принимает второй параметр, который является индексом, с которого начинается поиск в строке назад, что делает вещи эффективными и простыми.

// Shorten a string to less than maxLen characters without truncating words.
function shorten(str, maxLen, separator = ' ') {
  if (str.length <= maxLen) return str;
  return str.substr(0, str.lastIndexOf(separator, maxLen));
}

Это пример вывода:

for (var i = 0; i < 50; i += 3) 
  console.log(i, shorten("The quick brown fox jumps over the lazy dog", i));

 0 ""
 3 "The"
 6 "The"
 9 "The quick"
12 "The quick"
15 "The quick brown"
18 "The quick brown"
21 "The quick brown fox"
24 "The quick brown fox"
27 "The quick brown fox jumps"
30 "The quick brown fox jumps over"
33 "The quick brown fox jumps over"
36 "The quick brown fox jumps over the"
39 "The quick brown fox jumps over the lazy"
42 "The quick brown fox jumps over the lazy"
45 "The quick brown fox jumps over the lazy dog"
48 "The quick brown fox jumps over the lazy dog"

А для слизни:

for (var i = 0; i < 50; i += 10) 
  console.log(i, shorten("the-quick-brown-fox-jumps-over-the-lazy-dog", i, '-'));

 0 ""
10 "the-quick"
20 "the-quick-brown-fox"
30 "the-quick-brown-fox-jumps-over"
40 "the-quick-brown-fox-jumps-over-the-lazy"
18 голосов
/ 28 марта 2011

Кажется, что все забывают, что indexOf принимает два аргумента - строку для сопоставления и индекс символа для начала просмотра.Вы можете разбить строку на первый пробел после 10 символов.

function cutString(s, n){
    var cut= s.indexOf(' ', n);
    if(cut== -1) return s;
    return s.substring(0, cut)
}
var s= "this is a long string i cant display";
cutString(s, 10)

/*  returned value: (String)
this is a long
*/
10 голосов
/ 01 июля 2016

Lodash имеет функцию, специально написанную для этого: _.truncate

const truncate = _.truncate
const str = 'The quick brown fox jumps over the lazy dog'

truncate(str, {
  length: 30, // maximum 30 characters
  separator: /,?\.* +/ // separate by spaces, including preceding commas and periods
})

// 'The quick brown fox jumps...'
7 голосов
/ 11 июня 2014

Основываясь на ответе NT3RP, который не обрабатывает некоторые угловые случаи, я сделал этот код. Это гарантирует не возвращать текст с событием size> maxLength, в конце которого был добавлен многоточие ....

Это также обрабатывает некоторые угловые случаи, такие как текст, который имеет одно слово> maxLength

shorten: function(text,maxLength,options) {
    if ( text.length <= maxLength ) {
        return text;
    }
    if ( !options ) options = {};
    var defaultOptions = {
        // By default we add an ellipsis at the end
        suffix: true,
        suffixString: " ...",
        // By default we preserve word boundaries
        preserveWordBoundaries: true,
        wordSeparator: " "
    };
    $.extend(options, defaultOptions);
    // Compute suffix to use (eventually add an ellipsis)
    var suffix = "";
    if ( text.length > maxLength && options.suffix) {
        suffix = options.suffixString;
    }

    // Compute the index at which we have to cut the text
    var maxTextLength = maxLength - suffix.length;
    var cutIndex;
    if ( options.preserveWordBoundaries ) {
        // We use +1 because the extra char is either a space or will be cut anyway
        // This permits to avoid removing an extra word when there's a space at the maxTextLength index
        var lastWordSeparatorIndex = text.lastIndexOf(options.wordSeparator, maxTextLength+1);
        // We include 0 because if have a "very long first word" (size > maxLength), we still don't want to cut it
        // But just display "...". But in this case the user should probably use preserveWordBoundaries:false...
        cutIndex = lastWordSeparatorIndex > 0 ? lastWordSeparatorIndex : maxTextLength;
    } else {
        cutIndex = maxTextLength;
    }

    var newText = text.substr(0,cutIndex);
    return newText + suffix;
}

Полагаю, вы можете легко удалить зависимость jquery, если это вас беспокоит.

2 голосов
/ 01 июля 2016
function shorten(str,n) {
  return (str.match(RegExp(".{"+n+"}\\S*"))||[str])[0];
}

shorten("Hello World", 3); // "Hello"

// SHORTEN STRING TO WHOLE WORDS
function shorten(s,l) {
  return (s.match(new RegExp(".{"+l+"}\\S*"))||[s])[0];
}

console.log( shorten("The quick brown fox jumps over the lazy dog", 6) ); // "The quick"
2 голосов
/ 11 июня 2015

Я выбрал другой подход. Хотя мне требовался аналогичный результат, я хотел, чтобы возвращаемое значение было меньше указанной длины.

function wordTrim(value, length, overflowSuffix) {
    value = value.trim();
    if (value.length <= length) return value;
    var strAry = value.split(' ');
    var retString = strAry[0];
    for (var i = 1; i < strAry.length; i++) {
        if (retString.length >= length || retString.length + strAry[i].length + 1 > length) break;
        retString += " " + strAry[i];
    }
    return retString + (overflowSuffix || '');
}

Редактировать Я немного изменил его здесь: Пример JSFiddle . Он присоединяется к исходному массиву вместо конкатенации.

function wordTrim(value, length, overflowSuffix) {
    if (value.length <= length) return value;
    var strAry = value.split(' ');
    var retLen = strAry[0].length;
    for (var i = 1; i < strAry.length; i++) {
        if(retLen == length || retLen + strAry[i].length + 1 > length) break;
        retLen+= strAry[i].length + 1
    }
    return strAry.slice(0,i).join(' ') + (overflowSuffix || '');
}
1 голос
/ 30 апреля 2019
shorten(str, maxLen, appendix, separator = ' ') {
if (str.length <= maxLen) return str;
let strNope = str.substr(0, str.lastIndexOf(separator, maxLen));
return (strNope += appendix);

}

var s = "это длинная строка, и я не могу объяснить все";сократить (с, 10, '...')

/ * "это .." * /

1 голос
/ 26 июля 2018

Вы можете использовать truncate однострочник ниже:

const text = "The string that I want to truncate!";

const truncate = (str, len) => str.substring(0, (str + ' ').lastIndexOf(' ', len));

console.log(truncate(text, 14));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...