Split string at space after certain number of characters in Javascript

11,843

Solution 1

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

const chunks = str.match(/.{1,154}(\s|$)/g);

some examples:

const str = 'the quick brown fox jumps over the lazy dog';

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

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.

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/>");
    });
}

Note (as has been pointed out in the comments) that this code will fail if one of the words in the string is longer than the length of the chunks.

Solution 2

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.

Share:
11,843

Related videos on Youtube

Leminnes
Author by

Leminnes

Updated on June 09, 2022

Comments

  • Leminnes
    Leminnes almost 2 years

    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.

    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.

    Here is my javascript code at the moment:

    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:

    <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/

    Thank you! I appreciate any assistance!

  • blex
    blex about 6 years
    I think you misinterpreted the question. He needs to split the text into chunks, not just cut it and get the first chunk :-) (sorry if I misspelled your name in my answer)
  • Scott Marcus
    Scott Marcus about 6 years
    @blex I don't know about that. I asked him a couple of clarifying questions in his original question and this is what I believe he's asking. We'll see I guess.
  • blex
    blex about 6 years
    Try his JS Fiddle with a really long text, and you'll see multiple textareas as a result, while your answer only outputs one textContent
  • Scott Marcus
    Scott Marcus about 6 years
    @blex I did. It seems to be doing what my code does (except his doesn't get the count right).
  • Scott Marcus
    Scott Marcus about 6 years
    @blex I had a couple of UI corrections to make to better emulate what the OP's fiddle does if that's what you mean, but the algorithm hasn't changed.
  • Adriano
    Adriano about 6 years
    You don't want to create a loop that goes 154 times through the string just to count to 155. You know that you want to manipulate the string after the 154th character; just do it! ;)
  • Leminnes
    Leminnes about 6 years
    For whatever reason, when I try to use this on my local version, it does not work. I click the submit button and nothing happens. I'll keep messing around and see if I can get it to work.
  • Cory Kleiser
    Cory Kleiser about 6 years
    The loop is counting down from 154 until it gets to a space.
  • Leminnes
    Leminnes about 6 years
    I figured it out, I'm just an idiot. The others are right, I want to be able to display every string of that length.
  • Leminnes
    Leminnes about 6 years
    This worked quite well except that for the last string it cuts off the last word. Is there a way to fix that?
  • Nick
    Nick about 6 years
    Oops! Fixed the regexp now. Sorry about that - I should have noticed in my examples.
  • Leminnes
    Leminnes about 6 years
    Ah, thanks much! One more related but unrelated question. If I wanted to add a character, say a + to the end of every line but the very last one, would that be possible?
  • Nick
    Nick about 6 years
    You could change chunks[x] to chunks[x].replace(/(\s)$/, '$1+') or (if you want to get rid of the trailing whitespace on the first strings) chunks[x].replace(/\s+$/, '+')
  • Leminnes
    Leminnes about 6 years
    That worked perfectly. I should really learn more regex. It seems so powerful, just so immensely confusing haha
  • Nick
    Nick about 6 years
    Yes and Yes! There's a good site to play with them at regex101.com
  • Leminnes
    Leminnes about 6 years
    Final question for you, since I've been trying to figure it out without resorting to asking, but so far I have failed. Similar to above, how would I add a character, like + again, to the beginning of the strings in all but the first string?
  • Nick
    Nick about 6 years
    Replace chunks[x] with (x == 0 ? chunks[x] : '+' + chunks[x]).
  • Nick
    Nick about 6 years
    Note that in my solution (and in all these comments), you should use i instead of chunks[x] (since that is what i is set to in each iteration of forEach()).
  • Cody Moniz
    Cody Moniz over 4 years
    note: this will fail for words longer than (154) characters var str = 'the quick brown fox somersaulted over the lazy dog'; console.log(str.match(/.{1,10}(\s|$)/g)) (5) ["the quick ", "brown fox ", "mersaulted ", "over the ", "lazy dog"]
  • Nick
    Nick over 4 years
    @CodyMoniz you are right - but I don't know of any words that are that long. The longest word in an English dictionary is only 45 letters.

Related