正如标题所说,我有一个字符串,我想把它分成n个字符的片段。

例如:

var str = 'abcdefghijkl';

当n=3时,它会变成

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

有办法做到这一点吗?


当前回答

function str_split(string, length = 1) {
    if (0 >= length)
        length = 1;
    
    if (length == 1)
        return string.split('');

    var string_size = string.length;
    var result = [];

    for (let i = 0; i < string_size / length; i++)
        result[i] = string.substr(i * length, length);

    return result;
}

str_split(str, 3)

基准测试:http://jsben.ch/HkjlU(不同浏览器的结果不同)

结果(Chrome 104)

其他回答

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

上面的函数是我用于Base64分块的。它将创建一个每75个字符的换行符。

稍后再讨论,但这里有一个变化,比子字符串+数组push 1快一点。

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

作为for循环的一部分,预先计算结束值比在子字符串中进行内联计算要快。我已经在Firefox和Chrome上测试过了,它们都显示了加速。

你可以在这里试试

基于之前对这个问题的回答;下面的函数将分割一个字符串(str) n-number (size)的字符。

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>

如果你真的需要坚持使用.split和/或.raplace,那么使用/(?<=^(?:.{3})+)(?!$)/g

.split:

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

.replace:

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

/(?!$)/表示在字符串结束时不停止。没有它的:

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

忽略组/(?:…)/是为了防止数组中存在重复项。没有它的:

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

这里我们每隔n个字符就在一个字符串中穿插另一个字符串:

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;

};

如果我们像这样使用上面的语句:

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

我们得到:

亚美大陆煤层气有限公司|亚美大陆煤层气有限公司| aeg |坚毅不屈| e

这里我们做同样的事情,但是push到一个数组:

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;

};

然后运行它:

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

我们得到:

[“fooba”、“rbazt”、“ruck”]

如果有人知道简化上述代码的方法,请使用lmk,但它应该适用于字符串。