如何将字符串拆分为 n 个字符的段?

Posted

技术标签:

【中文标题】如何将字符串拆分为 n 个字符的段?【英文标题】:How can I split a string into segments of n characters? 【发布时间】:2011-09-09 17:05:34 【问题描述】:

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

例如:

var str = 'abcdefghijkl';

经过n=3的一些魔术,它会变成

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

有没有办法做到这一点?

【问题讨论】:

最佳答案隐藏在下方,请参阅***.com/a/6259539/984471 【参考方案1】:

如果您不想使用正则表达式...

var chunks = [];

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

jsFiddle.

...否则正则表达式解决方案非常好:)

【讨论】:

+1 因为如果 3 是 OP 建议的变量,我更喜欢这个。它比连接正则表达式字符串更具可读性。 如果你能把它包装成一个可以使用的有用函数 这比正则表达式选项快 10 倍以上,所以我会选择这个(在函数内部)jsbench.github.io/#9cb819bf1ce429575f8535a211f72d5a 我之前的声明适用于 Chromium(另外,我编辑之前的评论太晚了,因此是新的评论)。在 Firefox 上,它目前在我的机器上“仅”快了 30%,但这仍然更好。 这对于长长的字符串是否可持续?【参考方案2】:
str.match(/.3/g); // => ['abc', 'def', 'ghi', 'jkl']

【讨论】:

这适用于我的3,但返回null250。 ?【参考方案3】:

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

注意:使用1,3 而不是只使用3 来包含不是3 倍数的字符串长度的余数,例如:

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

更多细节:

    如果您的字符串可能包含换行符(您希望将其计为一个字符而不是拆分字符串),那么. 将不会捕获这些。请改用/[\s\S]1,3/。 (感谢@Mike)。 如果您的字符串为空,那么match() 将返回null,而您可能期望一个空数组。通过附加 || [] 来防止这种情况发生。

所以你可能会得到:

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) || []);

【讨论】:

这在技术上是更好的答案,因为它会从不能被 3 整除的字符串中抓取所有文本(它会抓取最后 2 或 1 个字符)。 使用[\s\S] 而不是.,以免换行失败。 您可能希望在每一行上开始一个新循环。如果您确实有换行符,它们可能表示某种类型的转换。 str.match(/.1,3/gm) 可能是更好的选择。 +1 小心: ''.match(/.1,3/g)''.match(/.3/g) 返回 null 而不是空数组。 数字3可以用变量代替吗?【参考方案4】:

在此问题的先前答案的基础上;以下函数将拆分字符串 (str) n 个 (size) 字符。

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

演示

(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;
&lt;div id="out"&gt;&lt;/div&gt;

【讨论】:

【参考方案5】:
function chunk(er)
return er.match(/.1,75/g).join('\n');

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

【讨论】:

也可以replace(/.1,75/g, '$&amp;\n').【参考方案6】:

一些不使用正则表达式的干净解决方案:

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

使用示例 - https://jsfiddle.net/maciejsikora/b6xppj4q/.

我还尝试将我的解决方案与被选为正确答案的正则表达式进行比较。一些测试可以在 jsfiddle -https://jsfiddle.net/maciejsikora/2envahrk/ 上找到。测试表明两种方法具有相似的性能,可能乍一看正则表达式解决方案要快一点,但请自行判断。

【讨论】:

【参考方案7】:

我的解决方案(ES6 语法):

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

我们甚至可以用这个创建一个函数:

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;

那么你就可以很容易地以可重用的方式调用函数了:

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

干杯

【讨论】:

【参考方案8】:

这里我们每隔 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'));

我们得到:

aag|aag|aeg|eag|e

在这里我们做同样的事情,但推送到一个数组:

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,但它应该适用于字符串。

【讨论】:

您的第一个 sn-p 没有按预期工作。我在这里修改:jsfiddle.net/omarojo/ksvx2txb/261【参考方案9】:

如果您确实需要坚持使用.split 和/或.raplace,请使用/(?&lt;=^(?:.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

【讨论】:

【参考方案10】:
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, []);

没有 REGEX 的清洁解决方案

【讨论】:

【参考方案11】:

这是一种无需正则表达式或显式循环的方法,尽管它稍微扩展了单行的定义:

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' ]

它的工作原理是将字符串拆分为单个字符的数组,然后使用Array.reduce 遍历每个字符。通常reduce 会返回单个值,但在这种情况下,单个值恰好是一个数组,并且当我们传递每个字符时,我们将其附加到该数组中的最后一项。一旦数组中的最后一项达到目标长度,我们就追加一个新的数组项。

【讨论】:

【参考方案12】:

稍后讨论,但这里的变体比子字符串 + 数组推送快一点。

// 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 中对其进行了测试,它们都显示了加速。

你可以试试here

【讨论】:

【参考方案13】:
    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)

【讨论】:

【参考方案14】:

试试这个简单的代码,它会像魔术一样工作!

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

【讨论】:

它有效,我 +1【参考方案15】:

如果您需要将一个非常大的 html 字符串拆分为较小的 html 字符串并将它们添加到 .txt 文件中的新行中,您可以在此处阅读我的答案。

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

【讨论】:

【参考方案16】:

我最喜欢的答案是 gouder hicham 的。但我对其进行了一些修改,以便对我更有意义。

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

这是代码的功能化版本。


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;

以及函数的用途:

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

结果如下:

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

【讨论】:

以上是关于如何将字符串拆分为 n 个字符的段?的主要内容,如果未能解决你的问题,请参考以下文章

如果字符串包含多个 \n,如何在每 25 个换行符(\n)上拆分一个字符串

您知道如何将字符串列表拆分为不同的变量吗?

动态规划之字符串拆分

如何将包含字符“\ n”的多行字符串拆分为bash中的字符串数组? [复制]

当 n 是随机的时,将字符串拆分为 n

如何将字符串拆分为多个部分?