开发者

chunk/split a string in Javascript without breaking words

Good day,

I would like to know if there is an easy way to chunk/split a string without breaking the words.

Eg:

var input = "Lorem ipsum dolor sit amet, consectetur  adipiscing elit. Proin placerat, nisi nec vulputate scelerisque, metus lectus ultricies massa, et luctus elit libe开发者_开发百科ro eu erat. Fusce vitae sem lacus, eu ullamcorper lectus. Lorem ipsum dolor sit amet, consectetur adipiscing elit.";

Should return an array like this if I break at 80 characters long:

var output = ["Lorem ipsum dolor sit amet, consectetur  adipiscing elit. Proin placerat, nisi",
"nec vulputate scelerisque, metus lectus ultricies massa, et luctus elit libero",
"eu erat. Fusce vitae sem lacus, eu ullamcorper lectus. Lorem ipsum dolor sit",
"amet, consectetur adipiscing elit."];

I found that really nice piece of code:

//http://phpjs.org/functions/chunk_split:369
function chunk_split (body, chunklen, end) {
    // Returns split line  
    // 
    // version: 1103.1210
    // discuss at: http://phpjs.org/functions/chunk_split
    // +   original by: Paulo Freitas
    // +      input by: Brett Zamir (http://brett-zamir.me)
    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: Theriault
    // *     example 1: chunk_split('Hello world!', 1, '*');
    // *     returns 1: 'H*e*l*l*o* *w*o*r*l*d*!*'
    // *     example 2: chunk_split('Hello world!', 10, '*');
    // *     returns 2: 'Hello worl*d!*'
    chunklen = parseInt(chunklen, 10) || 76;
    end = end || '\r\n';

    if (chunklen < 1) {
        return false;
    }

    return body.match(new RegExp(".{0," + chunklen + "}", "g")).join(end);
}

But I really doubt I can modify it so words aren't broken in half. Any tips?

Thank you!


Here's some brute force code that will do it:

function splitIntoLines(input, len) {
    var i;
    var output = [];
    var lineSoFar = "";
    var temp;
    var words = input.split(' ');
    for (i = 0; i < words.length;) {
        // check if adding this word would exceed the len
        temp = addWordOntoLine(lineSoFar, words[i]);
        if (temp.length > len) {
            if (lineSoFar.length == 0) {
                lineSoFar = temp;     // force to put at least one word in each line
                i++;                  // skip past this word now
            }
            output.push(lineSoFar);   // put line into output
            lineSoFar = "";           // init back to empty
        } else {
            lineSoFar = temp;         // take the new word
            i++;                      // skip past this word now
        }
    }
    if (lineSoFar.length > 0) {
        output.push(lineSoFar);
    }
    return(output);
}

function addWordOntoLine(line, word) {
    if (line.length != 0) {
        line += " ";
    }
    return(line += word);
}

If this routine encounters a single word longer than the desired line length, it will put it on a line by itself and will not break it up.

You can play with it here: http://jsfiddle.net/jfriend00/fbaLe/


This builds on @steve's answer but will split the string respecting word break so that the string is never longer than the specified length. This works more like a normal word wrap.

function chunkString(s, len)
{
    var curr = len, prev = 0;

    output = [];

    while(s[curr]) {
      if(s[curr++] == ' ') {
        output.push(s.substring(prev,curr));
        prev = curr;
        curr += len;
      }
      else
      {
        var currReverse = curr;
        do {
            if(s.substring(currReverse - 1, currReverse) == ' ')
            {
                output.push(s.substring(prev,currReverse));
                prev = currReverse;
                curr = currReverse + len;
                break;
            }
            currReverse--;
        } while(currReverse > prev)
      }
    }
    output.push(s.substr(prev)); 
    return output;
}


Something like this?

var n = 80;

while (n) { 
    if (input[n++] == ' ') { 
        break;  
    } 
}

output = input.substring(0,n).split(' ');
console.log(output);

UPDATED

Now that I re-read the question, here's an updated solution:

var len = 80;
var curr = len;
var prev = 0;

output = [];

while (input[curr]) {
    if (input[curr++] == ' ') {
        output.push(input.substring(prev,curr));
        prev = curr;
        curr += len;
    }
}
output.push(input.substr(prev));  


Thank to orourkedd, it iwas very useful. I just updated it with splitting.

private chunkString(str, len) {
    let input = str.trim().split(' ');
    let [index, output] = [0, []]
    output[index] = '';
    input.forEach(word => {
        let temp = `${output[index]} ${word}`.trim()
        if (temp.length <= len) {
            output[index] = temp;
        } else {
            index++;
            output[index] = word;
        }
    })
    return output
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜