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

IT技术 javascript string substring
2021-02-11 04:40:16

我不太擅长 JavaScript 中的字符串操作,我想知道如何在不切断任何单词的情况下缩短字符串。我知道如何使用子字符串,但不知道如何使用 indexOf 或任何非常好的东西。

假设我有以下字符串:

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

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

“这是我无法分辨的长字符串”

我希望它完成这个词,直到出现空格。

6个回答

如果我理解正确,您想将字符串缩短到一定长度(例如缩短"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(" ")))
这总是切到最后一句话。
2021-03-17 04:40:16
如果在比 maxLength 短的字符串上使用它,最后一个单词会被截断。也许@AndrewJuniorHoward 已经说明了此 ( maxLength + 1)的修复,但我通过简单地在顶部添加此行来修复它:var yourString += " ";
2021-03-20 04:40:16
@josh“.replace”在“jQuery 函数”中不起作用是绝对不正确的。甚至没有任何诸如“jQuery 函数”之类的东西。
2021-03-25 04:40:16
那不应该是“maxLength + 1”。如果 maxLength 大于或等于完整的句子长度,则不包括最后一个单词。但感谢您的解决方案。
2021-04-07 04:40:16
不幸的是,如果你拿走fox jumps over the lazy dog一部分,结果将是The quick brown ,当它应该是The quick brown fox
2021-04-10 04:40:16

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

"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
好吧,这并不能真正正常工作,有时我会传递最大值,例如,如果最后一个单词已经是 30 个字符,那么它的长度已经超过 60!即使将长度设置为{30}
2021-03-16 04:40:16
它指的是第一个(在这种情况下也是唯一的)子表达式匹配 - 括号中的内容。$0 将引用整个匹配项,在这种情况下是整个字符串。
2021-03-24 04:40:16
@josh您应该能够使用正则表达式对象使最大长度成为变量: t.replace(new RegExp("^(.{"+length+"}[^\s]*).*"), "$1")
2021-03-27 04:40:16
太棒了,我从字面上用谷歌搜索了这个问题一百万种方式,只能找到一个适用于 php 的工作版本,与此无关,并且涉及循环。
2021-03-31 04:40:16
@Hamish 您的选项效果很好,但如果长度超过,它也包括最后一个单词。如果最大字数限制超过但没有使其正常工作,我尝试更改正则表达式以排除最后一个单词。我们怎样才能做到这一点?
2021-04-09 04:40:16

我有点惊讶,对于这样一个简单的问题,有这么多难以阅读的答案,有些答案,包括所选的答案,都不起作用。

我通常希望结果字符串最多为 maxLen字符。我也使用相同的函数来缩短 URL 中的 slug。

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"
我完全忘记了 lastIndexOf()。接得好!
2021-03-15 04:40:16
这不处理字符串中不出现分隔符的边缘情况
2021-03-21 04:40:16
如果 str>maxLen,这将返回空字符串。通过添加 if(str.split(separator)[0].length>maxLen) return str.split(separator)[0].substr(0,maxLen-2)+"..."; 解决了这个问题。
2021-03-25 04:40:16
这种崩溃如果由于某种原因strundefined我加了if (!str || str.length <= maxLen) return str;
2021-03-28 04:40:16
@shrewquest 它有效。如果分隔符不在字符串中,则返回字符串本身 if str.length <= maxLen否则它返回一个空字符串。
2021-04-11 04:40:16

每个人似乎都忘记了 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
*/
请注意,如果需要硬边界,可以将 indexOf 替换为 lastIndexOf。
2021-03-20 04:40:16

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