如何将字符串拆分为 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
,但返回null
和250
。 ?【参考方案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;
<div id="out"></div>
【讨论】:
【参考方案5】:function chunk(er)
return er.match(/.1,75/g).join('\n');
上面的函数是我用于 Base64 分块的。它将创建一个每 75 个字符的换行符。
【讨论】:
也可以replace(/.1,75/g, '$&\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
,请使用/(?<=^(?:.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)上拆分一个字符串