Jawaban:
var str = 'abcdefghijkl';
console.log(str.match(/.{1,3}/g));
Catatan: Gunakan {1,3}
sebagai ganti hanya {3}
untuk memasukkan sisa untuk panjang string yang bukan kelipatan 3, misalnya:
console.log("abcd".match(/.{1,3}/g)); // ["abc", "d"]
Beberapa kehalusan:
.
tidak akan menangkapnya. Gunakan /[\s\S]{1,3}/
sebagai gantinya. (Trims @Mike).match()
akan kembali null
ketika Anda mungkin mengharapkan array kosong. Lindungi dari ini dengan menambahkan || []
.Jadi, Anda mungkin berakhir dengan:
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]
alih-alih .
agar tidak gagal di baris baru.
''.match(/.{1,3}/g)
dan ''.match(/.{3}/g)
kembali null
sebagai ganti array kosong.
Jika Anda tidak ingin menggunakan ekspresi reguler ...
var chunks = [];
for (var i = 0, charsLength = str.length; i < charsLength; i += 3) {
chunks.push(str.substring(i, i + 3));
}
jsFiddle .
... kalau tidak solusi regex cukup bagus :)
3
variabel seperti yang disarankan oleh OP. Ini lebih mudah dibaca daripada menggabungkan string regexp.
Membangun jawaban sebelumnya untuk pertanyaan ini; fungsi berikut akan membagi string ( str
) n-number ( size
) karakter.
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>
Solusi saya (sintaks ES6):
const source = "8d7f66a9273fc766cd66d1d";
const target = [];
for (
const array = Array.from(source);
array.length;
target.push(array.splice(0,2).join(''), 2));
Kami bahkan dapat membuat fungsi dengan ini:
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;
}
Kemudian Anda dapat memanggil fungsi dengan mudah dengan cara yang dapat digunakan kembali:
const source = "8d7f66a9273fc766cd66d1d";
const target = splitStringBySegmentLength(source, 2);
Bersulang
function chunk(er){
return er.match(/.{1,75}/g).join('\n');
}
Fungsi di atas adalah apa yang saya gunakan untuk Base64 chunking. Itu akan membuat satu baris 75 karakter.
replace(/.{1,75}/g, '$&\n')
.
Di sini kita menyelingi string dengan string lain setiap n karakter:
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;
};
jika kita menggunakan cara di atas seperti ini:
console.log(splitString(3,'|', 'aagaegeage'));
kita mendapatkan:
aag | aag | aeg | eag | e
dan di sini kita melakukan hal yang sama, tetapi dorong ke array:
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;
};
dan kemudian jalankan:
console.log(sperseString(5, 'foobarbaztruck'));
kita mendapatkan:
['fooba', 'rbazt', 'ruck']
jika seseorang mengetahui cara untuk menyederhanakan kode di atas, lmk, tetapi harus berfungsi dengan baik untuk string.
Beberapa solusi bersih tanpa menggunakan ekspresi reguler:
/**
* 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;
};
Contoh penggunaan - https://jsfiddle.net/maciejsikora/b6xppj4q/ .
Saya juga mencoba membandingkan solusi saya dengan regexp yang dipilih sebagai jawaban yang benar. Beberapa tes dapat ditemukan di jsfiddle - https://jsfiddle.net/maciejsikora/2envahrk/ . Pengujian menunjukkan bahwa kedua metode memiliki kinerja yang sama, mungkin pada solusi regexp tampilan pertama sedikit lebih cepat, tetapi menilai sendiri.
Dengan .split
:
var arr = str.split( /(?<=^(?:.{3})+)(?!$)/ ) // [ 'abc', 'def', 'ghi', 'jkl' ]
dan .replace
akan:
var replaced = str.replace( /(?<=^(.{3})+)(?!$)/g, ' || ' ) // 'abc || def || ghi || jkl'
/(?!$)/
adalah untuk berhenti sebelum akhir /$/
, tanpa adalah:
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 || '
mengabaikan grup /(?:
... )/
tidak perlu di .replace
tetapi di .split
menambahkan grup ke arr:
var arr = str.split( /(?<=^(.{3})+)(?!$)/ ) // [ 'abc', 'abc', 'def', 'abc', 'ghi', 'abc', 'jkl' ]
Berikut cara untuk melakukannya tanpa ekspresi reguler atau loop eksplisit, meskipun sedikit memperluas definisi liner:
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' ]
Ini bekerja dengan memisahkan string menjadi array karakter individu, lalu gunakan Array.reduce
untuk beralih ke setiap karakter. Biasanya reduce
akan mengembalikan nilai tunggal, tetapi dalam kasus ini nilai tunggal terjadi menjadi array, dan ketika kami melewati setiap karakter kita menambahkannya ke item terakhir dalam array itu. Setelah item terakhir dalam array mencapai panjang target, kami menambahkan item array baru.
Beberapa saat kemudian untuk diskusi tetapi di sini variasi yang sedikit lebih cepat daripada dorongan substring + array.
// 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));
}
Pra-menghitung nilai akhir sebagai bagian dari for loop lebih cepat daripada melakukan inline math di dalam substring. Saya sudah mengujinya di Firefox dan Chrome dan keduanya menunjukkan peningkatan.
Anda bisa mencobanya di sini