2011-06-07 40 views

回答

226

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

注:使用{1,3},而不是仅仅{3}以包含字符串长度余说不是3的倍数,例如:

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


一对夫妇更细微之处:

  1. 如果你的字符串可能包含(要算作一个字符,而不是分割字符串)换行符,那么.将不会捕获这些。改为使用/[\s\S]{1,3}/。 (谢谢@Mike)。
  2. 如果您的字符串为空,那么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) || []);

+9

+1不错,在{{1,3}'catch :)上 – alex 2011-06-07 00:35:31

+0

这在技术上是更好的答案,因为它会从不能被3整除的字符串中获取所有文本(它会抓取最后2或1个字符)。 – Erik 2011-06-07 00:36:02

+6

使用'[\ s \ S]'而不是'.',以免在换行符上失败。 – 2011-06-07 00:42:44

28

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

var chunks = []; 

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

jsFiddle

...否则,正则表达式的解决方案是相当不错的:)

+13

+1 becaus e正则表达式使我感到痛苦。 – Marty 2011-06-07 00:34:11

+1

+1 cos我更喜欢这个,如果'3'是OP所建议的变量。它比连接正则表达式字符串更可读。 – 2011-06-07 00:56:36

+0

如果只有你可以将其包装成一个有用的函数,可以使用 – momomo 2016-09-28 09:49:27

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

大厦前面的这个问题的答案;以下函数将拆分字符串(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>

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

以上功能是我使用的Base64分块。它将创建一个有75个字符的换行符。

+0

也可以'替换(/。{1,75}/g,'$&\ n')'。 – alex 2016-01-15 08:41:39

0

一些干净的解决方案,而无需使用正则表达式:

/** 
* 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/上找到。测试显示,这两种方法都有类似的表现,也许在第一眼看正则表达式解决方案速度稍快一点,但请自行判断。

0

这里有一个快速的双内衬commafies号:

function commafy(inVal){ 
    var ary = String(inVal).match(/(\d{0,2})((?:\d{3})*)([^\d].*$)/i); 
    return (ary[1] == "" ? [] : [ary[1]]).splice(1, 0, ary[2].match(/[0-9]{3}/g)).join(",") + ary[3]; 
} 

如果它被传播出去,这可能是这样的:

function commafy(inVal){ 
    var aryChunks = []; 
    var inVal = String(inVal); 
    var aryPart1 = inVal.match(/(\d{0,2})((?:\d{3})*)([^\d].*$)/i); 
    if(aryPart1[1] != ""){ 
     aryChunks.push(aryPart1[1]); 
    } 
    var aryPart2 = aryPart1[2].match(/[0-9]{3}/g); 
    aryChunks.splice(1, 0, aryPart2); 
    var outVal = aryChunks.join(","); 
    outVal += aryPart1[3]; 
    return outVal; 
} 

首先,aryPart1被分配一个正则表达式匹配由[0至2个数字]组成,后跟[长度为3的倍数的字符串],然后是[零个或一个非数字及其他所有内容]。

然后,如果不是“”,我们将[0到2数字]附加到aryChunk。

之后,我们将[长度为3的倍数的字符串]和正则表达式匹配成一个名为aryPart2的[3字符片断]的数组,然后我们拼接成aryChunk。

现在aryChunks包含我们将加入一个逗号并分配给outVal的块。

剩下要做的就是将[零个或一个非数字及其他]附加到outVal,并将outVal返回给调用者。

根据OP,正则表达式1中的{0,2}和{3}以及正则表达式2中的{3}可以是使块成为任意长度的变量,并且正则表达式中的\ d可以更改为“”如果你希望它的工作不仅仅是数字。

我花了太长时间写这篇文章,所以可能会出现一些小故障。指出他们,我会调整他们的时间。

0

我的解决方案(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); 

Cheers

相关问题