How can I split a string into segments of n characters?

JavascriptArraysStringSplit

Javascript Problem Overview


As the title says, I've got a string and I want to split into segments of n characters.

For example:

var str = 'abcdefghijkl';

after some magic with n=3, it will become

var arr = ['abc','def','ghi','jkl'];

Is there a way to do this?

Javascript Solutions


Solution 1 - Javascript

var str = 'abcdefghijkl';
console.log(str.match(/.{1,3}/g));

Note: Use {1,3} instead of just {3} to include the remainder for string lengths that aren't a multiple of 3, e.g:

console.log("abcd".match(/.{1,3}/g)); // ["abc", "d"]


A couple more subtleties:

  1. If your string may contain newlines (which you want to count as a character rather than splitting the string), then the . won't capture those. Use /[\s\S]{1,3}/ instead. (Thanks @Mike).
  2. If your string is empty, then match() will return null when you may be expecting an empty array. Protect against this by appending || [].

So you may end up with:

var str = 'abcdef \t\r\nghijkl';
var parts = str.match(/[\s\S]{1,3}/g) || [];
console.log(parts);

console.log(''.match(/[\s\S]{1,3}/g) || []);

Solution 2 - Javascript

If you didn't want to use a regular expression...

var chunks = [];

for (var i = 0, charsLength = str.length; i < charsLength; i += 3) {
    chunks.push(str.substring(i, i + 3));
}

jsFiddle.

...otherwise the regex solution is pretty good :)

Solution 3 - Javascript

str.match(/.{3}/g); // => ['abc', 'def', 'ghi', 'jkl']

Solution 4 - Javascript

Building on the previous answers to this question; the following function will split a string (str) n-number (size) of characters.

function chunk(str, size) {
    return str.match(new RegExp('.{1,' + size + '}', 'g'));
}

Demo

(function() {
  function chunk(str, size) {
    return str.match(new RegExp('.{1,' + size + '}', 'g'));
  }
  
  var str = 'HELLO WORLD';
  println('Simple binary representation:');
  println(chunk(textToBin(str), 8).join('\n'));
  println('\nNow for something crazy:');
  println(chunk(textToHex(str, 4), 8).map(function(h) { return '0x' + h }).join('  '));
  
  // Utiliy functions, you can ignore these.
  function textToBin(text) { return textToBase(text, 2, 8); }
  function textToHex(t, w) { return pad(textToBase(t,16,2), roundUp(t.length, w)*2, '00'); }
  function pad(val, len, chr) { return (repeat(chr, len) + val).slice(-len); }
  function print(text) { document.getElementById('out').innerHTML += (text || ''); }
  function println(text) { print((text || '') + '\n'); }
  function repeat(chr, n) { return new Array(n + 1).join(chr); }
  function textToBase(text, radix, n) {
    return text.split('').reduce(function(result, chr) {
      return result + pad(chr.charCodeAt(0).toString(radix), n, '0');
    }, '');
  }
  function roundUp(numToRound, multiple) { 
    if (multiple === 0) return numToRound;
    var remainder = numToRound % multiple;
    return remainder === 0 ? numToRound : numToRound + multiple - remainder;
  }
}());

#out {
  white-space: pre;
  font-size: 0.8em;
}

<div id="out"></div>

Solution 5 - Javascript

If you really need to stick to .split and/or .raplace, then use /(?<=^(?:.{3})+)(?!$)/g

For .split:

var arr = str.split( /(?<=^(?:.{3})+)(?!$)/ )
// [ 'abc', 'def', 'ghi', 'jkl' ]

For .replace:

var replaced = str.replace( /(?<=^(?:.{3})+)(?!$)/g, ' || ' )
// 'abc || def || ghi || jkl'



/(?!$)/ is to not stop at end of the string. Without it's:

var arr = str.split( /(?<=^(?:.{3})+)/ )
// [ 'abc', 'def', 'ghi', 'jkl' ] // is fine
var replaced = str.replace( /(?<=^(.{3})+)/g, ' || ')
// 'abc || def || ghi || jkl || ' // not fine

Ignoring group /(?:...)/ is to prevent duplicating entries in the array. Without it's:

var arr = str.split( /(?<=^(.{3})+)(?!$)/ )
// [ 'abc', 'abc', 'def', 'abc', 'ghi', 'abc', 'jkl' ] // not fine
var replaced = str.replace( /(?<=^(.{3})+)(?!$)/g, ' || ' )
// 'abc || def || ghi || jkl' // is fine

Solution 6 - Javascript

const chunkStr = (str, n, acc) => {		
	if (str.length === 0) {
		return acc
	} else {
		acc.push(str.substring(0, n));
		return chunkStr(str.substring(n), n, acc);
	}
}
const str = 'abcdefghijkl';
const splittedString = chunkStr(str, 3, []);

Clean solution without REGEX

Solution 7 - Javascript

My solution (ES6 syntax):

const source = "8d7f66a9273fc766cd66d1d";
const target = [];
for (
    const array = Array.from(source);
    array.length;
    target.push(array.splice(0,2).join(''), 2));

We could even create a function with this:

function splitStringBySegmentLength(source, segmentLength) {
    if (!segmentLength || segmentLength < 1) throw Error('Segment length must be defined and greater than/equal to 1');
    const target = [];
    for (
        const array = Array.from(source);
        array.length;
        target.push(array.splice(0,segmentLength).join('')));
    return target;
}

Then you can call the function easily in a reusable manner:

const source = "8d7f66a9273fc766cd66d1d";
const target = splitStringBySegmentLength(source, 2);

Cheers

Solution 8 - Javascript

try this simple code and it will work like magic !

let letters = "abcabcabcabcabc";
// we defined our variable or the name whatever
let a = -3;
let finalArray = [];
for (let i = 0; i <= letters.length; i += 3) {
    finalArray.push(letters.slice(a, i));
  a += 3;
}
// we did the shift method cause the first element in the array will be just a string "" so we removed it
finalArray.shift();
// here the final result
console.log(finalArray);

Solution 9 - Javascript

function chunk(er){
return er.match(/.{1,75}/g).join('\n');
}

Above function is what I use for Base64 chunking. It will create a line break ever 75 characters.

Solution 10 - Javascript

Here we intersperse a string with another string every n characters:

export const intersperseString = (n: number, intersperseWith: string, str: string): string => {
  
  let ret = str.slice(0,n), remaining = str;
  
  while (remaining) {
    let v = remaining.slice(0, n);
    remaining = remaining.slice(v.length);
    ret += intersperseWith + v;
  }
  
  return ret;
  
};

if we use the above like so:

console.log(splitString(3,'|', 'aagaegeage'));

we get:

> aag|aag|aeg|eag|e

and here we do the same, but push to an array:

export const sperseString = (n: number, str: string): Array<string> => {
  
  let ret = [], remaining = str;
  
  while (remaining) {
    let v = remaining.slice(0, n);
    remaining = remaining.slice(v.length);
    ret.push(v);
  }
  
  return ret;
  
};

and then run it:

console.log(sperseString(5, 'foobarbaztruck'));

we get:

> [ 'fooba', 'rbazt', 'ruck' ]

if someone knows of a way to simplify the above code, lmk, but it should work fine for strings.

Solution 11 - Javascript

Coming a little later to the discussion but here a variation that's a little faster than the substring + array push one.

// substring + array push + end precalc
var chunks = [];

for (var i = 0, e = 3, charsLength = str.length; i < charsLength; i += 3, e += 3) {
    chunks.push(str.substring(i, e));
}

Pre-calculating the end value as part of the for loop is faster than doing the inline math inside substring. I've tested it in both Firefox and Chrome and they both show speedup.

You can try it here

Solution 12 - Javascript

My favorite answer is gouder hicham's. But I revised it a little so that it makes more sense to me.

let myString = "Able was I ere I saw elba";

let splitString = [];
for (let i = 0; i < myString.length; i = i + 3) {
    splitString.push(myString.slice(i, i + 3));
}

console.log(splitString);

Here is a functionalized version of the code.


function stringSplitter(myString, chunkSize) {
    let splitString = [];
    for (let i = 0; i < myString.length; i = i + chunkSize) {
        splitString.push(myString.slice(i, i + chunkSize));
    }
    return splitString;
}

And the function's use:

let myString = "Able was I ere I saw elba";
let mySplitString = stringSplitter(myString, 3);
console.log(mySplitString);

And it's result:

>(9['Abl', 'e w', 'as ', 'I e', 're ', 'I s', 'aw ', 'elb', 'a']

Solution 13 - Javascript

Some clean solution without using regular expressions:

/**
* Create array with maximum chunk length = maxPartSize
* It work safe also for shorter strings than part size
**/
function convertStringToArray(str, maxPartSize){

  const chunkArr = [];
  let leftStr = str;
  do {

    chunkArr.push(leftStr.substring(0, maxPartSize));
    leftStr = leftStr.substring(maxPartSize, leftStr.length);

  } while (leftStr.length > 0);

  return chunkArr;
};

Usage example - https://jsfiddle.net/maciejsikora/b6xppj4q/.

I also tried to compare my solution to regexp one which was chosen as right answer. Some test can be found on jsfiddle - https://jsfiddle.net/maciejsikora/2envahrk/. Tests are showing that both methods have similar performance, maybe on first look regexp solution is little bit faster, but judge it Yourself.

Solution 14 - Javascript

Here's a way to do it without regular expressions or explicit loops, although it's stretching the definition of a one liner a bit:

const input = 'abcdefghijlkm';

// Change `3` to the desired split length.
const output = input.split('').reduce((s, c) => {let l = s.length-1; (s[l] && s[l].length < 3) ? s[l] += c : s.push(c); return s;}, []);

console.log(output);  // output: [ 'abc', 'def', 'ghi', 'jlk', 'm' ]

It works by splitting the string into an array of individual characters, then using Array.reduce to iterate over each character. Normally reduce would return a single value, but in this case the single value happens to be an array, and as we pass over each character we append it to the last item in that array. Once the last item in the array reaches the target length, we append a new array item.

Solution 15 - Javascript

    var b1 = ""; 
    function myFunction(n) { 
    if(str.length>=3){
     var a = str.substring(0,n);
     b1 += a+ "\n"
     str = str.substring(n,str.length)
     myFunction(n) 
    } 
    else{ 
    if(str.length>0){
    b1 += str 
    } 
    console.log(b1)
     } 
    }
  myFunction(4)

Solution 16 - Javascript

If you need to split a very big html string in smaller html strings and add them in a .txt file in new lines you can read my answer here.

https://stackoverflow.com/a/70287092/13795525

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBenView Question on Stackoverflow
Solution 1 - JavascriptDavid TangView Answer on Stackoverflow
Solution 2 - JavascriptalexView Answer on Stackoverflow
Solution 3 - JavascriptmaericsView Answer on Stackoverflow
Solution 4 - JavascriptMr. PolywhirlView Answer on Stackoverflow
Solution 5 - JavascriptДенис ДечевView Answer on Stackoverflow
Solution 6 - JavascriptseriouspatView Answer on Stackoverflow
Solution 7 - JavascriptJesus GonzalezView Answer on Stackoverflow
Solution 8 - Javascriptgouder hichamView Answer on Stackoverflow
Solution 9 - JavascriptDave BrownView Answer on Stackoverflow
Solution 10 - JavascriptAlexander MillsView Answer on Stackoverflow
Solution 11 - JavascriptDragonaireView Answer on Stackoverflow
Solution 12 - Javascriptgarydavenport73View Answer on Stackoverflow
Solution 13 - JavascriptMaciej SikoraView Answer on Stackoverflow
Solution 14 - JavascriptMalvineousView Answer on Stackoverflow
Solution 15 - JavascriptNITISH KUMARView Answer on Stackoverflow
Solution 16 - JavascriptPietroView Answer on Stackoverflow