在Javascript中有一定数量的字符后在空格处分割字符串

时间:2021-08-18 17:36:45

I am attempting to create a tool that takes an input text and splits it into chunks of text at a certain # of characters. However, I need to make sure it does not split the text in the middle of a word.

我正在尝试创建一个工具,该工具接受输入文本,并将其分割为若干个字符的文本块。但是,我需要确保它不会在一个单词中间分割文本。

In my case, I am splitting the string after 155 characters.

在我的例子中,我将字符串分割为155个字符。

I've done quite a lot of searching to try and find a solution, but I fear it may be more complicated than my knowledge of Javascript allows me to figure out. I believe I just need to make some sort of logic that has the splitter backtrack to a space to split if it is in the middle of a word, but I am not sure how to write out such a thing.

我已经做了大量的搜索,试图找到一个解决方案,但我担心它可能比我的Javascript知识更复杂。我相信我只需要做一些逻辑,让分裂者回溯到一个空间,如果它在一个词的中间,但我不确定如何写出这样的东西。

Here is my javascript code at the moment:

以下是我目前的javascript代码:

function splitText() {
    "use strict";
    var str = document.getElementById("user_input").value;
    var size = 195;
    var chunks = new Array(Math.ceil(str.length / size)),
        nChunks = chunks.length;

    var newo = 0;
    for (var i = 0, o = 0; i < nChunks; ++i, o = newo) {
          newo += size;
          chunks[i] = str.substr(o, size);
    }

    var newq = 0;
    for (var x = 0, q = 0; x < nChunks; ++x, q = newq) {
        $("#display").append("<textarea readonly>" + chunks[x] + "</textarea><br/>");
    }
}

And here is my HTML:

这是我的HTML:

<body>
    <content>
        <h1>Text Splitter</h1>
        <form>
            <label>Enter a Message</label>
            <input type="text" name="message" id="user_input">
        </form>
        <form>
            <input type="button" onclick="splitText();" id="submit" value="Submit!"> <br/>
        </form>
        <label>Your split message: </label>
        <p><span id='display'></span></p>
    </content>
</body>

Here is the code in its current working form, if you'd like to take a look: https://jsfiddle.net/add4s7rs/7/

这里是当前工作表单中的代码,如果您想看一下:https://jsfiddle.net/add4s7rs/7/

Thank you! I appreciate any assistance!

谢谢你们!我很感谢任何帮助!

4 个解决方案

#1


5  

A short and simple way to split a string into chunks up to a certain length using a regexp:

使用regexp将字符串分割成一定长度的块的简单方法:

console.log(str.match(/.{1,154}(\s|$)/g));

some examples:

一些例子:

var str = 'the quick brown fox jumps over the lazy dog';
console.log(str.match(/.{1,10}(\s|$)/g))
Array [ "the quick ", "brown fox ", "jumps over ", "the lazy ", "dog" ]
console.log(str.match(/.{1,15}(\s|$)/g))
Array [ "the quick brown ", "fox jumps over ", "the lazy dog" ]

This works because quantifiers (in this case {1,154}) are by default greedy and will attempt to match as many characters as they can. putting the (\s|$) behind the .{1,154} forces the match to terminate on a whitespace character or the end of the string. So .{1,154}(\s|$) will match up to 154 characters followed by a whitespace character. The /g modifier then makes it continue to match through the entire string.

这样做是因为量词(在本例中为{1,154})在默认情况下是贪婪的,并且将尝试匹配尽可能多的字符。将(\s|$)置于.{1,154}之后,将迫使匹配终止于空格字符或字符串的末尾。因此,{1,154}(\s|$)将匹配最多154个字符,然后是空格字符。然后,/g修改器使它在整个字符串中继续匹配。

To put this in the context of your function:

在你的职能范围内:

function splitText() {
    "use strict";
    var str = document.getElementById("user_input").value;
    var chunks = str.match(/.{1,154}(\s|$)/g);

    chunks.forEach(function (i,x) {
        $("#display").append("<textarea readonly>" + chunks[x] + "</textarea><br/>");
    });
}

#2


1  

you could use a simple function like this:

您可以使用如下简单的函数:

function split(string) {
  for(i=154; i>=0; i--) {
    if(string.charAt(i) == " ") {
      var newString1 = string.slice(0, i);
      var newString2 = string.slice(i);
    }
  }
}

Instead of assigning to separate strings you can always put them into an array if you'd like as well.

如果你愿意,你可以把它们放到一个数组中,而不是分配给单独的字符串。

#3


0  

A more simple approach would be to split the entered text into an array of the individual words and then loop through the array and re-build the string, keeping a count of whether adding the next word in the array will put you over your max size.

一种更简单的方法是将输入的文本分割成单个单词的数组,然后在数组中循环并重新构建字符串,计算在数组中添加下一个单词是否会使您超出最大大小。

Also, note that you should keep all of your form elements inside a single form.

另外,请注意,应该将所有表单元素都保存在一个表单中。

Lastly, you should not use inline HTML event attributes (onclick, etc.). That was a technique we used 20+ years ago before we had standards and best-practices and, unfortunately the use of the technique is so prolific, it just will not die the abrupt death it deserves. There are many reasons not to code this way and instead use the modern approach of doing all event handling with .addEventListener() in a separate JavaScript.

最后,不应该使用内联HTML事件属性(onclick,等等)。这是我们20多年前使用的一种技术,那时我们还没有标准和最佳实践,不幸的是,这种技术的使用非常丰富,它不会像它应该的那样突然死亡。有很多理由不以这种方式编写代码,而是使用现代方法,在独立的JavaScript中使用. addeventlistener()来处理所有事件处理。

// Don't set variables to properties of DOM elements, set them to the element
// itself so that if you ever want a different property value, you don't have to
// re-scan the DOM for the same element again.
var str = document.getElementById("user_input");
var output = document.getElementById("display");

document.getElementById("go").addEventListener("click",function(){
    "use strict";
    const size = 155; // Constant is more appropriate here
    var words = str.value.split(/\s+/g); // Create array of all words in field
    
    var finalString = "";
    
    // Loop through array
    for(var i = 0; i < words.length; i++){
      if((finalString + " " + words[i]).length <= size){
        finalString += " " + words[i];
      } else {
        break; // Max size exceeded - quit loop!
      }
    }
    
    // Update field with correct value
    output.textContent = finalString;
    console.log(finalString.length);
});
textarea {
  width:500px;
  height:100px;
}
<h1>Text Splitter</h1>
        <form>
            <label>Enter a Message
            <textarea name="message" id="user_input">This is a test of the emergency broadcast system. If this had been an actual emergency, you would have been informed as to what instructions you should follow in order to remain safe at all times.</textarea></label>
            <input type="button" id="go" value="Submit!"><br>
        </form>
        <label>Your split message: </label>
        <p><span id='display'></span></p>

#4


0  

This solution goes on the logic of having a maximum chunk size and then reducing that size if need be to fit your word. Uses a while loop and a little bit of C style logic.

这个解决方案的逻辑是拥有一个最大的块大小,如果需要的话,可以缩小这个大小。使用while循环和一点C风格的逻辑。

function splitText() {
    "use strict";

    var str = document.getElementById("user_input").value;

    // Maximum allowed chunk size
    let MAX_CHUNK_SIZE = 155;
    let chunks = new Array();
    let current_chunk_position = 0;

    while(current_chunk_position < str.length){

        let current_substring = str.substr(current_chunk_position, MAX_CHUNK_SIZE);

        let last_index = current_substring.lastIndexOf(" ") > 0 ? current_substring.lastIndexOf(" ") : MAX_CHUNK_SIZE;

        let chunk = str.substr(current_chunk_position, last_index);
        chunks.push(chunk);

        current_chunk_position += last_index;
    }

    var newq = 0;
    for (var x = 0, q = 0; x < nChunks; ++x, q = newq) {
        $("#display").append("<textarea readonly>" + chunks[x] + "</textarea><br/>");
    }
}

#1


5  

A short and simple way to split a string into chunks up to a certain length using a regexp:

使用regexp将字符串分割成一定长度的块的简单方法:

console.log(str.match(/.{1,154}(\s|$)/g));

some examples:

一些例子:

var str = 'the quick brown fox jumps over the lazy dog';
console.log(str.match(/.{1,10}(\s|$)/g))
Array [ "the quick ", "brown fox ", "jumps over ", "the lazy ", "dog" ]
console.log(str.match(/.{1,15}(\s|$)/g))
Array [ "the quick brown ", "fox jumps over ", "the lazy dog" ]

This works because quantifiers (in this case {1,154}) are by default greedy and will attempt to match as many characters as they can. putting the (\s|$) behind the .{1,154} forces the match to terminate on a whitespace character or the end of the string. So .{1,154}(\s|$) will match up to 154 characters followed by a whitespace character. The /g modifier then makes it continue to match through the entire string.

这样做是因为量词(在本例中为{1,154})在默认情况下是贪婪的,并且将尝试匹配尽可能多的字符。将(\s|$)置于.{1,154}之后,将迫使匹配终止于空格字符或字符串的末尾。因此,{1,154}(\s|$)将匹配最多154个字符,然后是空格字符。然后,/g修改器使它在整个字符串中继续匹配。

To put this in the context of your function:

在你的职能范围内:

function splitText() {
    "use strict";
    var str = document.getElementById("user_input").value;
    var chunks = str.match(/.{1,154}(\s|$)/g);

    chunks.forEach(function (i,x) {
        $("#display").append("<textarea readonly>" + chunks[x] + "</textarea><br/>");
    });
}

#2


1  

you could use a simple function like this:

您可以使用如下简单的函数:

function split(string) {
  for(i=154; i>=0; i--) {
    if(string.charAt(i) == " ") {
      var newString1 = string.slice(0, i);
      var newString2 = string.slice(i);
    }
  }
}

Instead of assigning to separate strings you can always put them into an array if you'd like as well.

如果你愿意,你可以把它们放到一个数组中,而不是分配给单独的字符串。

#3


0  

A more simple approach would be to split the entered text into an array of the individual words and then loop through the array and re-build the string, keeping a count of whether adding the next word in the array will put you over your max size.

一种更简单的方法是将输入的文本分割成单个单词的数组,然后在数组中循环并重新构建字符串,计算在数组中添加下一个单词是否会使您超出最大大小。

Also, note that you should keep all of your form elements inside a single form.

另外,请注意,应该将所有表单元素都保存在一个表单中。

Lastly, you should not use inline HTML event attributes (onclick, etc.). That was a technique we used 20+ years ago before we had standards and best-practices and, unfortunately the use of the technique is so prolific, it just will not die the abrupt death it deserves. There are many reasons not to code this way and instead use the modern approach of doing all event handling with .addEventListener() in a separate JavaScript.

最后,不应该使用内联HTML事件属性(onclick,等等)。这是我们20多年前使用的一种技术,那时我们还没有标准和最佳实践,不幸的是,这种技术的使用非常丰富,它不会像它应该的那样突然死亡。有很多理由不以这种方式编写代码,而是使用现代方法,在独立的JavaScript中使用. addeventlistener()来处理所有事件处理。

// Don't set variables to properties of DOM elements, set them to the element
// itself so that if you ever want a different property value, you don't have to
// re-scan the DOM for the same element again.
var str = document.getElementById("user_input");
var output = document.getElementById("display");

document.getElementById("go").addEventListener("click",function(){
    "use strict";
    const size = 155; // Constant is more appropriate here
    var words = str.value.split(/\s+/g); // Create array of all words in field
    
    var finalString = "";
    
    // Loop through array
    for(var i = 0; i < words.length; i++){
      if((finalString + " " + words[i]).length <= size){
        finalString += " " + words[i];
      } else {
        break; // Max size exceeded - quit loop!
      }
    }
    
    // Update field with correct value
    output.textContent = finalString;
    console.log(finalString.length);
});
textarea {
  width:500px;
  height:100px;
}
<h1>Text Splitter</h1>
        <form>
            <label>Enter a Message
            <textarea name="message" id="user_input">This is a test of the emergency broadcast system. If this had been an actual emergency, you would have been informed as to what instructions you should follow in order to remain safe at all times.</textarea></label>
            <input type="button" id="go" value="Submit!"><br>
        </form>
        <label>Your split message: </label>
        <p><span id='display'></span></p>

#4


0  

This solution goes on the logic of having a maximum chunk size and then reducing that size if need be to fit your word. Uses a while loop and a little bit of C style logic.

这个解决方案的逻辑是拥有一个最大的块大小,如果需要的话,可以缩小这个大小。使用while循环和一点C风格的逻辑。

function splitText() {
    "use strict";

    var str = document.getElementById("user_input").value;

    // Maximum allowed chunk size
    let MAX_CHUNK_SIZE = 155;
    let chunks = new Array();
    let current_chunk_position = 0;

    while(current_chunk_position < str.length){

        let current_substring = str.substr(current_chunk_position, MAX_CHUNK_SIZE);

        let last_index = current_substring.lastIndexOf(" ") > 0 ? current_substring.lastIndexOf(" ") : MAX_CHUNK_SIZE;

        let chunk = str.substr(current_chunk_position, last_index);
        chunks.push(chunk);

        current_chunk_position += last_index;
    }

    var newq = 0;
    for (var x = 0, q = 0; x < nChunks; ++x, q = newq) {
        $("#display").append("<textarea readonly>" + chunks[x] + "</textarea><br/>");
    }
}