根据最大字符长度分割字符串,但考虑单词完整性

3
在我的程序中,我可以接收各种长度的字符串并将它们发送以进行翻译。如果这些字符串具有特定的字符长度,则会出现错误,因此我想在出错之前检查和分割这些字符串。但是,我不能只是在单词中间分割字符串,还需要考虑单词本身的完整性。例如:
let str = "this is an input example of one sentence that contains a bit of words and must be split"
let splitStringArr = [];

// If string is larger than X (for testing make it 20) characters
if(str.length > 20) {
    // Split string sentence into smaller strings, keep words intact
    //...
    // example of result would be
    // splitStringArr = ['this is an input', 'example of one sentence' 'that contains...', '...']
    // instead of ['this is an input exa' 'mple of one senten' 'ce that contains...']
}

但我不确定如何分割一句话并仍然考虑到句子长度。

解决此问题的方法是迭代字符串,将每个单词添加到其中,并每次检查它是否超过最大长度,否则开始一个新的数组索引,或者还有更好/现有的方法吗?


一个快速的问题,为什么第一个被分割的字符串是 this is an input 而不是 this is an input example?如果你只想要少于 maxLength 的单词,那么为什么 'example of one sentence 的字符串长度大于20? - Code Maniac
4个回答

5
你可以使用匹配、向前查看和单词边界,|.+ 取出结尾处长度小于最大长度的字符串。

let str = "this is an input example of one sentence that contains a bit of words and must be split"

console.log(str.match(/\b[\w\s]{20,}?(?=\s)|.+$/g))


如果您不仅想要长度小于maxLength的字符串,那么您可以简单地使用/\b[\w\s]{20,}?(?=\s)/g - Code Maniac
太棒了!有没有办法更新这个表达式,使其返回时不带前导空格?因此,在您的示例中,它将返回类似于 [ "这是一个输入示例", "由一个句子组成", "包含一些单词", "必须被分割" ] - dasis
@dasis,这里是链接 - OfirD
如果这是一个段落,每个句子都包含标点符号怎么办?例如,“这是一个输入,一个包含一些单词并且必须被分割的句子。 ” - Awolad Hossain

5

这里有一个使用reduce的示例。

const str = "this is an input example of one sentence that contains a bit of words and must be split";

// Split up the string and use `reduce`
// to iterate over it
const temp = str.split(' ').reduce((acc, c) => {

  // Get the number of nested arrays
  const currIndex = acc.length - 1;

  // Join up the last array and get its length
  const currLen = acc[currIndex].join(' ').length;

  // If the length of that content and the new word
  // in the iteration exceeds 20 chars push the new
  // word to a new array
  if (currLen + c.length > 20) {
    acc.push([c]);

  // otherwise add it to the existing array
  } else {
    acc[currIndex].push(c);
  }

  return acc;

}, [[]]);

// Join up all the nested arrays
const out = temp.map(arr => arr.join(' '));

console.log(out);


2
你需要的是lastIndexOf函数。
在这个例子中,maxOkayStringLength是字符串长度可以达到的最大值,超过这个长度会导致错误。
myString.lastIndexOf(/\s/,maxOkayStringLength);

-- 编辑 --

lastIndexOf不接受正则表达式参数,但是stackoverflow上有另一篇帖子提供了可以实现该功能的代码:

JavaScript的String.indexOf()是否有允许使用正则表达式的版本?


2
我建议:
1)通过空格符号将字符串分割,以获得单词数组。
2)开始逐个选择单词重新创建字符串...
3)如果下一个单词使字符串超过最大长度,则使用此单词开始新字符串。
类似这样:
const splitString = (str, lineLength) => {
  const arr = ['']

  str.split(' ').forEach(word => {
    if (arr[arr.length - 1].length + word.length > lineLength) arr.push('')
    arr[arr.length - 1] += (word + ' ')
  })

  return arr.map(v => v.trim())
}
const str = "this is an input example of one sentence that contains a bit of words and must be split"
console.log(splitString(str, 20))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接