在JavaScript中缩短string而不切断单词
我对JavaScript中的string操作不是很好,我想知道如何在不删除任何单词的情况下缩短string。 我知道如何使用子string,但不是indexOf或任何其他的东西。
说我有以下string:
text = "this is a long string I cant display"
我想把它缩小到10个字符,但是如果它不以空格结束,那就完成这个单词。 我不希望stringvariables看起来像这样:
“这是一个很长的string我不能dis”
我希望它完成这个词,直到发生空间。
如果我理解正确的话,你要把一个string缩短到一定的长度(例如缩短"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(" ")))
有很多方法可以做到,但是正则expression式是一种有用的一行方法:
"this is a longish string of text".replace(/^(.{11}[^\s]*).*/, "$1"); //"this is a longish"
此expression式返回前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
每个人似乎都忘记了indexOf有两个参数 – 要匹配的string和开始查找的字符索引。 您可以在10个字符后的第一个空格处打破string。
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 */
我有些惊讶,对于这样一个简单的问题,有太多的答案难以阅读,有些不适用,包括select的问题。
我通常希望结果string最多为 maxLen
字符。 我使用这个相同的function来缩短URL中的slu </s>。
str.lastIndexOf(searchValue[, fromIndex])
接受第二个参数,该参数是在string中向后search的索引,使事情变得高效和简单。
// 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 </s>:
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"
基于NT3RP的答案,不处理一些angular落的情况下,我做了这个代码。 它保证不返回大小> maxLength事件的文本,最后添加一个省略号...
这也处理一些angular落的情况下,像一个单词是> 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的依赖如果这困扰你。
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...'
我采取了不同的方法。 虽然我需要一个类似的结果,我想保持我的返回值小于指定的长度。
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示例 。 它重新join原始数组而不是连接。
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 || ''); }
你可以用这个修饰空格:
var trimmedString = flabbyString.replace(/^\s*(.*)\s*$/, '$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 ..."
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"
为了什么值得我写这个截断字边界而不留在string末尾的标点符号或空格:
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 ? '…' : ''; 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--; }
从@ NT3RP更新我发现,如果string恰好碰到一个空格第一次周围将最终删除该字,使您的string比它可能短一个字。 所以我只是扔了一个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)