JS: Splitting a long string into strings with char limit while avoiding splitting words
Asked Answered
J

5

16

I am trying to take a large block of text and split it into multiple strings that are 148 characters each, while avoiding cutting off words.

I have this now, which is splitting words:

var length = shortData.new.length;

if (length < 160){

  outputString[0] = shortData.new;
  document.write(outputString[0]);

}


if (length > 160 && length < 308){

  outputString[0] = shortData.new.substring(0,148);
  outputString[1] = shortData.new.substring(148,length);    

  document.write(outputString[0]+"(txt4more..)");   
  document.write(outputString[1]);      

}


if (length > 308 && length < 468){


  outputString[0] = shortData.new.substring(0,148);
  outputString[1] = shortData.new.substring(148,308);   
  outputString[2] = shortData.new.substring(308,length);    

  document.write(outputString[0]+"(txt4more..)");   
  document.write(outputString[1]+"(txt4more..)");   
  document.write(outputString[2]);      

}


if (length > 468 && length < 641){


  outputString[0] = shortData.new.substring(0,148);
  outputString[1] = shortData.new.substring(148,308);   
  outputString[2] = shortData.new.substring(308,468);   
  outputString[3] = shortData.new.substring(468,length);    

  document.write(outputString[0]+"(txt4more..)");   
  document.write(outputString[1]+"(txt4more..)");   
  document.write(outputString[2]+"(txt4more..)");   
  document.write(outputString[3]);      

}
Joist answered 2/10, 2011 at 5:3 Comment(8)
Don't use "new" as a variable name in Javascript. It's a reserved word, so it won't work in IE, and even though it probably will work in other browsers, it shouldn't.Stilu
that's the JSON object I'm returning from an API I'm using, not my fault :(Joist
jrbaldwinn I see. I'm writing a function to do it now. How would you like it to behave if a word ever has more than 148 characters in it? break the word, or have an element that's more than 148 characters?Stilu
PaulPro: I need the function to create multiple strings that are all 148 characters each or less, based on the closest word, thank you!Joist
I just mean in the situation where a word happens to be longer than 148 characters. That might not ever happen, but I should still handle it somehow, because as it is right now the function will enter an infinite loop when it finds a word that long. It either needs to break the word into two groups, or put the entire word into the array as an element by itself even though the word is longer than 148 characters. SupercalifragilisticexpialidociousSupercalifragilisticexpialidociousSupercalifragilisticexpialidociousSupercalifragilisticexpialidociousSupercalifragilisticexpialidociousStilu
The source material will never have that happen, so I don't have to think about that crazinessJoist
@jrbladwin Lol alright then. I'll leave it undefined. Also do you want spaces on the ends of the resulting string, like (say we're splitting every 11 characters instead of 148): "Hello World Test". Do you want ["Hello World", "Test"], or ["Hello World", " Test"]Stilu
Nope, no spaces are needed, thank you!Joist
S
29

You can use this function, just pass in your string and the length and it will return the array, like:

var outputString = splitter(shortData['new'], 148);

The function:

function splitter(str, l){
    var strs = [];
    while(str.length > l){
        var pos = str.substring(0, l).lastIndexOf(' ');
        pos = pos <= 0 ? l : pos;
        strs.push(str.substring(0, pos));
        var i = str.indexOf(' ', pos)+1;
        if(i < pos || i > pos+l)
            i = pos;
        str = str.substring(i);
    }
    strs.push(str);
    return strs;
}

Example usage:

splitter("This is a string with several characters.\
120 to be precise I want to split it into substrings of length twenty or less.", 20);

Outputs:

["This is a string","with several","characters. 120 to",
"be precise I want","to split it into","substrings of",
"length twenty or","less."]
Stilu answered 2/10, 2011 at 5:46 Comment(1)
I would also add this line to the function, to make sure that the special characters are not counted as symbols: str = str.replace(/[\s\r\n]+/, ' ');Fleeting
C
3

You are going to have to pad some of your strings, to make them have the number of characters you require.

var lines= s.match(/(.{1,147}\s)\s*/g);
Chondroma answered 2/10, 2011 at 5:59 Comment(3)
A nice one-liner, but this doesn't match the last part of the string if it doesn't contain a delimiter.Abernon
var lines= s.match(/(.{1,30}(\s|$))\s*/g);Sternutation
It cuts the word if it's longer than the limit.Weltpolitik
O
1

You could use lastIndexOf() on a substr() of length 148 to find where to break the original string, remove that and loop while the length is > 148, like this:

var myText = "ad aenean adipiscing elit eget eleifend phasellus aenean lobortis vero venenatis ultricies eget iaculis ac neque nibh dignissim eleifend erat et in in justo sollicitudin mattis maecenas purus quis mi sed molestie integer magna non hendrerit nulla id neque augue suspendisse in in eget consectetuer et cubilia eu ullamcorper morbi elementum sed sed pharetra quam velit ante pellentesque eros nullam lobortis lorem fringilla libero elit nonummy purus sodales mauris sagittis praesent aenean in ut nullam ultricies quam aliquam arcu quisque semper lacinia lacinia sodales imperdiet ante venenatis suspendisse amet ante tellus nec nibh lorem in viverra magna cursus elit erat lobortis mattis purus pellentesque velit pellentesque dolor quam id mauris nibh pellentesque augue vel posuere aptent varius vivamus parturient hac ligula libero a varius sollicitudin sed dictumst morbi eros vestibulum donec purus turpis urna vel nisl quisque vulputate tristique non sed risus viverra varius tincidunt hendrerit ac dui mollis quam nunc suspendisse mattis volutpat vulputate integer ipsum cursus erat justo eu vestibulum sed blandit ac mi ligula montes sollicitudin vitae vel lacus imperdiet orci tincidunt sed imperdiet nunc vehicula pellentesque orci gravida diam non ut wisi sit et massa congue id scelerisque et mauris arcu nunc litora dignissim urna ea nullam magna felis duis pellentesque ultricies tincidunt vel pede fusce nunc sed interdum cursus wisi qui pulvinar wisi consectetuer fames sed hendrerit vitae velit viverra malesuada eu magna vehicula vivamus augue sagittis curabitur rutrum fringilla vivamus nisl enim eros elit vestibulum duis et duis erat sit auctor ac ipsum in et lacinia eu magna accumsan in nulla a sed massa maecenas ultricies duis dignissim sem augue id posuere lacus felis nisl quam ultricies urna dui curabitur morbi ante ut est eget tellus pulvinar mollis elementum tellus malesuada sollicitudin ligula fusce eget libero metus cras ligula felis nunc porttitor sit at";
var MAX_LENGTH = 148;

while (myText.length > MAX_LENGTH) {
    var s = myText.substr(0, MAX_LENGTH);
    var i = s.lastIndexOf(" ");
    alert(myText.substr(0, i));
    myText = myText.substr(i + 1, myText.length);
}
alert(myText);
Ology answered 2/10, 2011 at 5:10 Comment(0)
T
0

Without thinking to much about it, I would do something like this, just not in pseudo code

if string length > 148
    for i=148;i<string length;i+148
        if character at i = space
            add substring(i-148 to i) to output[]
        else
            add substring(i-148 to lastindoxof space) to output[]
            set i to lastindoxof space + 1)
    if i-148 != string length
        add substring (i-148 to string length -1) to output[]
Turkmen answered 2/10, 2011 at 5:17 Comment(0)
M
0

Had to come up with something similar for my project.

const addLineToResult = ({ content, result }) => {
    result.push(content);
};

const handleReadLine = ({ fullString, config, limit }) => {
    const start = config.counter;
    const end = config.counter + limit + 1;
    const result = config.result;

    for (let i = start; i < end; i++) {
        config.counter++;

        if (fullString[i] === '\n' || !fullString[i]) {
            addLineToResult({ content: fullString.slice(start, i).trim(), result });
            break;
        } else if (i === end - 1) {
            if (fullString[i] !== ' ') {
                for (let j = i; j >= start; j--) {
                    if (fullString[j] === ' ') {
                        addLineToResult({ content: fullString.slice(start, j).trim(), result });
                        config.counter = j;

                        break;
                    }
                }
            } else {
                addLineToResult({ content: fullString.slice(start, end).trim(), result });
            }
        }
    }
};

const handleGetClampedString = ({ fullString, limit }) => {
    const config = {
        counter: 0,
        result: [],
    };

    do {
        handleReadLine({ fullString, config, limit });
    } while (config.counter <= fullString.length);

    return config.result;
};

console.log(handleGetClampedString({ fullString: `This is a very long string that excceds the limit of characters or symbols in each line.\nIt needs to be split and then sent to an array.`, limit: 40 }));

Run it with,

handleGetClampedString({ fullString: `<your string>`, limit: 20 });
Mcquade answered 16/3, 2023 at 19:12 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.