缩短字符串而不在JavaScript中剪切单词

时间:2011-03-28 03:04:21

标签: javascript string substring

我对JavaScript中的字符串操作不太熟悉,我想知道如何在不删除任何字的情况下缩短字符串。我知道如何使用substring,但不知道indexOf或其他任何东西。

说我有以下字符串:

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

我想将其减少到10个字符,但如果它不以空格结尾,请完成单词。我不希望字符串变量看起来像这样:

  

“这是一个很长的字符串,我不能说”

我想让它完成这个词直到空格出现。

26 个答案:

答案 0 :(得分:150)

如果我理解正确,您希望将字符串缩短到一定长度(例如,将"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(" ")))

答案 1 :(得分:83)

有很多方法可以做到这一点,但正则表达式是一种有用的单行方法:

"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

答案 2 :(得分:50)

令我感到惊讶的是,对于像这样的简单问题,有很多难以阅读的答案,而且包括所选答案在内的一些答案不起作用。

我通常希望结果字符串最多为 maxLen个字符。 我也使用相同的功能来缩短URL中的slu ..

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"

对于slu ::

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"

答案 3 :(得分:18)

每个人似乎都忘记了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
*/

答案 4 :(得分:9)

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...'

答案 5 :(得分:7)

根据NT3RP的答案,它没有处理一些极端情况,我已经制作了这段代码。 它保证不返回大小为&gt;的文本。 maxLength事件最后添加了省略号...

这也可以处理一些角落案例,例如一个单词为&gt;的文本。最大长度

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依赖,如果这让你烦恼的话。

答案 6 :(得分:2)

我采取了不同的方法。虽然我需要类似的结果,但我希望保持我的返回值小于指定的长度。

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 Example。它重新加入原始数组而不是连接。

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

答案 7 :(得分:2)

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"

答案 8 :(得分:1)

您可以在下面使用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));

答案 9 :(得分:1)

“意大利面配番茄和菠菜”

如果您不想将单词切成两半

第一次迭代:

acc:0 / acc + cur.length = 5 / newTitle = ['Pasta'];

第二次迭代:

acc:5 / acc +当前长度= 9 / newTitle = ['Pasta','with'];

第三次迭代:

acc:9 / acc +当前长度= 15 / newTitle = ['Pasta','with','tomato'];

第四次迭代:

acc:15 / acc +当前长度= 18(限制范围)/ newTitle = ['Pasta','with','tomato'];

const limitRecipeTitle = (title, limit=17)=>{
    const newTitle = [];
    if(title.length>limit){
        title.split(' ').reduce((acc, cur)=>{
            if(acc+cur.length <= limit){
                newTitle.push(cur);
            }
            return acc+cur.length;
        },0);
    }

    return `${newTitle.join(' ')} ...`
}

输出:番茄意面...

答案 10 :(得分:1)

打字稿,并带有省略号:)

export const sliceByWord = (phrase: string, length: number, skipEllipses?: boolean): string => {
  if (phrase.length < length) return phrase
  else {
    let trimmed = phrase.slice(0, length)
    trimmed = trimmed.slice(0, Math.min(trimmed.length, trimmed.lastIndexOf(' ')))
    return skipEllipses ? trimmed : trimmed + '…'
  }
}

答案 11 :(得分:1)

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 =““这是一个很长的字符串,我无法全部解释”; 缩短(s,10,'...')

/ *“这是..” * /

答案 12 :(得分:1)

我迟到了,但这是一个小而简单的解决方案,我想出了回复一些词。

它与您对字符的要求没有直接关系,但它提供了我认为您所追求的结果

function truncateWords(sentence, amount, tail) {
  const words = sentence.split(' ');

  if (amount >= words.length) {
    return sentence;
  }

  const truncated = words.slice(0, amount);
  return `${truncated.join(' ')}${tail}`;
}

const sentence = 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.';

console.log(truncateWords(sentence, 10, '...'));

请参阅此处的工作示例: https://jsfiddle.net/bx7rojgL/

答案 13 :(得分:1)

这排除了最后一个词而不是包含它。

function smartTrim(str, length, delim, appendix) {
    if (str.length <= length) return str;

    var trimmedStr = str.substr(0, length+delim.length);

    var lastDelimIndex = trimmedStr.lastIndexOf(delim);
    if (lastDelimIndex >= 0) trimmedStr = trimmedStr.substr(0, lastDelimIndex);

    if (trimmedStr) trimmedStr += appendix;
    return trimmedStr;
}

用法:

smartTrim(yourString, 11, ' ', ' ...')
"The quick ..."

答案 14 :(得分:0)

你可以用这个修剪空格:

var trimmedString = flabbyString.replace(/^\s*(.*)\s*$/, '$1');

答案 15 :(得分:0)

找不到投票解决方案令人满意。所以我写的东西有点通用,可以在文本的第一部分和最后部分工作(类似于substr,但适用于单词)。您还可以设置是否要在字符计数中保留空格。

    function chopTxtMinMax(txt, firstChar, lastChar=0){
        var wordsArr = txt.split(" ");
        var newWordsArr = [];

        var totalIteratedChars = 0;
        var inclSpacesCount = true;

        for(var wordIndx in wordsArr){
            totalIteratedChars += wordsArr[wordIndx].length + (inclSpacesCount ? 1 : 0);
            if(totalIteratedChars >= firstChar && (totalIteratedChars <= lastChar || lastChar==0)){
                newWordsArr.push(wordsArr[wordIndx]);
            }
        }

        txt = newWordsArr.join(" ");
        return txt;
    }

答案 16 :(得分:0)

我为此迟到了,但是我认为这个功能正好满足了OP的要求。您可以轻松更改SENTENCE和LIMIT值以获得不同的结果。

function breakSentence(word, limit) {
  const queue = word.split(' ');
  const list = [];

  while (queue.length) {
    const word = queue.shift();

    if (word.length >= limit) {
      list.push(word)
    }
    else {
      let words = word;

      while (true) {
        if (!queue.length ||
            words.length > limit ||
            words.length + queue[0].length + 1 > limit) {
          break;
        }

        words += ' ' + queue.shift();
      }

      list.push(words);
    }
  }

  return list;
}

const SENTENCE = 'the quick brown fox jumped over the lazy dog';
const LIMIT = 11;

// get result
const words = breakSentence(SENTENCE, LIMIT);

// transform the string so the result is easier to understand
const wordsWithLengths = words.map((item) => {
  return `[${item}] has a length of - ${item.length}`;
});

console.log(wordsWithLengths);

此代码段的输出是LIMIT为11的地方:

[ '[the quick] has a length of - 9',
  '[brown fox] has a length of - 9',
  '[jumped over] has a length of - 11',
  '[the lazy] has a length of - 8',
  '[dog] has a length of - 3' ]

答案 17 :(得分:0)

为什么值得我写这个以截断到单词边界而不在字符串末尾留下标点符号或空格:

function truncateStringToWord(str, length, addEllipsis)
{
    if(str.length <= length)
    {
        // provided string already short enough
        return(str);
    }

    // cut string down but keep 1 extra character so we can check if a non-word character exists beyond the boundary
    str = str.substr(0, length+1);

    // cut any non-whitespace characters off the end of the string
    if (/[^\s]+$/.test(str))
    {
        str = str.replace(/[^\s]+$/, "");
    }

    // cut any remaining non-word characters
    str = str.replace(/[^\w]+$/, "");

    var ellipsis = addEllipsis && str.length > 0 ? '&hellip;' : '';

    return(str + ellipsis);
}

var testString = "hi stack overflow, how are you? Spare";
var i = testString.length;

document.write('<strong>Without ellipsis:</strong><br>');

while(i > 0)
{
  document.write(i+': "'+ truncateStringToWord(testString, i) +'"<br>');
  i--;
}

document.write('<strong>With ellipsis:</strong><br>');

i = testString.length;
while(i > 0)
{
  document.write(i+': "'+ truncateStringToWord(testString, i, true) +'"<br>');
  i--;
}

答案 18 :(得分:0)

具有边界条件,例如空句子和很长的第一个单词。此外,它不使用语言特定的字符串api / library。

function solution(message, k) {
    if(!message){
        return ""; //when message is empty
    }
    const messageWords = message.split(" ");
    let result = messageWords[0];
    if(result.length>k){
        return ""; //when length of first word itself is greater that k
    }
    for(let i = 1; i<messageWords.length; i++){
        let next = result + " " + messageWords[i];

        if(next.length<=k){
            result = next;
        }else{
            break;
        }
    }
    return result;
}

console.log(solution("this is a long string i cant display", 10));

答案 19 :(得分:0)

这里还有另一段代码,它会沿标点符号截断(正在寻找该代码,Google在这里找到了这个问题)。必须自己提出一个解决方案,所以这是我在15分钟内破解的内容。查找所有出现的。 ! ?并在其中任何小于define([ "dojo/_base/declare", "./../node_modules/xlsx/xlsx.js" //change it until it will be found ], function (declare, xlsx) { console.log(xlsx); var wb = xlsx.utils.book_new(); var ws = xlsx.utils.aoa_to_sheet(tempArr); xlsx.utils.book_append_sheet(wb, ws, "SheetJS"); /* Trigger Download with `writeFile` */ xlsx.writeFile(wb, "SheetJS.csv", {compression:true}); });

的位置截断
len

答案 20 :(得分:0)

这是一行解决方案。

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

function shorten(text,max) {
    return text && text.length > max ? text.slice(0,max).split(' ').slice(0, -1).join(' ') : text
}


console.log(shorten(text,10));

答案 21 :(得分:0)

我们可以使用lodash的truncate函数轻松地做到这一点

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

_.truncate('hi-diddly-ho there, neighborino', {
  'length': 24,
  'separator': ' '
 });
// => 'hi-diddly-ho there,...'

访问Lodash文档以获取更多信息。

答案 22 :(得分:0)

这是具有一些有用属性的单行版本:

  1. 处理\s正则表达式匹配的任何形式的空间
  2. 与输入长度无关(超过最大长度的任何内容都不会被扫描)
  3. 执行与输出长度无关(从最大长度向后扫描,并且不分割/连接字符串)
s.length > maxLen ? s.substring(0, s.substring(0, maxLen + 1).search(/\s+\S*$/)) : s

答案 23 :(得分:0)

如果您(已经)使用 lodash 库,则有一个名为 truncate 的函数可用于修剪字符串。

基于文档页面上的示例

_.truncate('hi-diddly-ho there, neighborino', {
  'length': 24,
  'separator': ' '
});
// => 'hi-diddly-ho there,...'

答案 24 :(得分:-1)

从@ NT3RP更新我发现如果字符串碰巧第一次碰到一个空格,它最终将删除该字,使你的字符串比一个字短。所以我只是在一个if else语句中检查maxLength是否落在空格上。

codepen.io

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

if (yourString[maxLength] !== " ") {

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

alert(trimmedString)

//re-trim if we are in the middle of a word
trimmedString = trimmedString.substr(0, Math.min(trimmedString.length, trimmedString.lastIndexOf(" ")))
}

else {
  var trimmedString = yourString.substr(0, maxLength);
}

alert(trimmedString)

答案 25 :(得分:-3)

您可以使用名为 substring 的 JavaScript 方法:

var content = "ABCD";
content.substring(0, 2);
console.log(content);

预期输出为 "D"
"ABC" 被修剪,因此可用内容为 "D"

相关问题