Câu trả lời:
var str = 'abcdefghijkl';
console.log(str.match(/.{1,3}/g));
Lưu ý: Sử dụng {1,3}
thay vì chỉ {3}
để bao gồm phần còn lại cho độ dài chuỗi không phải là bội số của 3, ví dụ:
console.log("abcd".match(/.{1,3}/g)); // ["abc", "d"]
Một vài tinh tế hơn:
.
sẽ không bắt được các dòng đó. Sử dụng /[\s\S]{1,3}/
thay thế. (Cảm ơn @Mike).match()
sẽ trả về null
khi bạn có thể mong đợi một mảng trống. Bảo vệ chống lại điều này bằng cách nối thêm || []
.Vì vậy, bạn có thể kết thúc với:
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) || []);
[\s\S]
thay vì .
để không thất bại trên dòng mới.
''.match(/.{1,3}/g)
và ''.match(/.{3}/g)
trả về null
thay vì một mảng trống.
Nếu bạn không muốn sử dụng biểu thức chính quy ...
var chunks = [];
for (var i = 0, charsLength = str.length; i < charsLength; i += 3) {
chunks.push(str.substring(i, i + 3));
}
jsFiddle .
... nếu không thì giải pháp regex khá tốt :)
3
biến được đề xuất bởi OP. Nó dễ đọc hơn nối chuỗi regrec.
Dựa trên các câu trả lời trước cho câu hỏi này; hàm sau sẽ phân tách một chuỗi ( str
) n-number ( size
) của các ký tự.
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>
Giải pháp của tôi (cú pháp ES6):
const source = "8d7f66a9273fc766cd66d1d";
const target = [];
for (
const array = Array.from(source);
array.length;
target.push(array.splice(0,2).join(''), 2));
Chúng tôi thậm chí có thể tạo ra một chức năng với điều này:
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;
}
Sau đó, bạn có thể gọi hàm dễ dàng theo cách có thể sử dụng lại:
const source = "8d7f66a9273fc766cd66d1d";
const target = splitStringBySegmentLength(source, 2);
Chúc mừng
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, []);
Giải pháp sạch mà không cần REGEX
function chunk(er){
return er.match(/.{1,75}/g).join('\n');
}
Chức năng trên là những gì tôi sử dụng cho chunking Base64. Nó sẽ tạo ra một ngắt dòng bao giờ 75 ký tự.
replace(/.{1,75}/g, '$&\n')
.
Ở đây chúng ta xen kẽ một chuỗi với một chuỗi khác mỗi n ký tự:
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;
};
nếu chúng ta sử dụng như trên:
console.log(splitString(3,'|', 'aagaegeage'));
chúng tôi nhận được:
aag | aag | aeg | eag | e
và ở đây chúng tôi làm tương tự, nhưng đẩy đến một mảng:
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;
};
và sau đó chạy nó:
console.log(sperseString(5, 'foobarbaztruck'));
chúng tôi nhận được:
['fooba', 'rbazt', 'ruck']
nếu ai đó biết một cách để đơn giản hóa đoạn mã trên, lmk, nhưng nó sẽ hoạt động tốt cho các chuỗi.
Một số giải pháp sạch mà không sử dụng biểu thức thông thường:
/**
* 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;
};
Ví dụ sử dụng - https://jsfiddle.net/maciejsikora/b6xppj4q/ .
Tôi cũng đã cố gắng so sánh giải pháp của mình với regrec một giải pháp được chọn là câu trả lời đúng. Một số thử nghiệm có thể được tìm thấy trên jsfiddle - https://jsfiddle.net/maciejsikora/2envahrk/ . Các thử nghiệm đang cho thấy rằng cả hai phương pháp đều có hiệu suất tương tự nhau, có thể trên giải pháp regrec nhìn đầu tiên nhanh hơn một chút, nhưng hãy tự đánh giá nó.
Với .split
:
var arr = str.split( /(?<=^(?:.{3})+)(?!$)/ ) // [ 'abc', 'def', 'ghi', 'jkl' ]
và .replace
sẽ là:
var replaced = str.replace( /(?<=^(.{3})+)(?!$)/g, ' || ' ) // 'abc || def || ghi || jkl'
/(?!$)/
là dừng lại trước khi kết thúc /$/
, mà không có:
var arr = str.split( /(?<=^(?:.{3})+)/ ) // [ 'abc', 'def', 'ghi', 'jkl' ] // I don't know why is not [ 'abc', 'def', 'ghi', 'jkl' , '' ], comment?
var replaced = str.replace( /(?<=^(.{3})+)/g, ' || ') // 'abc || def || ghi || jkl || '
bỏ qua nhóm /(?:
... )/
là không cần trong .replace
nhưng trong .split
việc thêm các nhóm vào mảng:
var arr = str.split( /(?<=^(.{3})+)(?!$)/ ) // [ 'abc', 'abc', 'def', 'abc', 'ghi', 'abc', 'jkl' ]
Đây là một cách để làm điều đó mà không cần các biểu thức thông thường hoặc các vòng lặp rõ ràng, mặc dù nó kéo dài định nghĩa của một lớp lót một chút:
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' ]
Nó hoạt động bằng cách chia chuỗi thành một mảng các ký tự riêng lẻ, sau đó sử dụng Array.reduce
để lặp qua từng ký tự. Thông thường reduce
sẽ trả về một giá trị duy nhất, nhưng trong trường hợp này, giá trị đơn lẻ là một mảng và khi chúng ta chuyển qua từng ký tự, chúng ta sẽ thêm nó vào mục cuối cùng trong mảng đó. Khi mục cuối cùng trong mảng đạt đến độ dài mục tiêu, chúng tôi sẽ thêm một mục mảng mới.
Đến một lúc sau để thảo luận nhưng ở đây một biến thể nhanh hơn một chút so với chuỗi con + mảng đẩy một.
// 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));
}
Tính toán trước giá trị cuối như một phần của vòng lặp for nhanh hơn so với thực hiện phép toán nội tuyến bên trong chuỗi con. Tôi đã thử nghiệm nó trên cả Firefox và Chrome và cả hai đều hiển thị tốc độ.
Bạn có thể thử nó ở đây