Risposte:
var str = 'abcdefghijkl';
console.log(str.match(/.{1,3}/g));
Nota: utilizzare {1,3}invece di {3}includere solo il resto per lunghezze di stringa che non sono un multiplo di 3, ad esempio:
console.log("abcd".match(/.{1,3}/g)); // ["abc", "d"]
Un altro paio di sottigliezze:
.non li catturerà. Usa /[\s\S]{1,3}/invece. (Grazie @Mike).match()verrà restituita nullquando ci si potrebbe aspettare un array vuoto. Proteggiti da questo aggiungendo || [].Quindi potresti finire con:
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]invece di .per non fallire su newline.
''.match(/.{1,3}/g) e ''.match(/.{3}/g)restituisce nullinvece di un array vuoto.
Se non volevi usare un'espressione regolare ...
var chunks = [];
for (var i = 0, charsLength = str.length; i < charsLength; i += 3) {
chunks.push(str.substring(i, i + 3));
}
jsFiddle .
... altrimenti la soluzione regex è abbastanza buona :)
3è variabile come suggerito dall'OP. È più leggibile che concatenare una stringa regexp.
Basandosi sulle risposte precedenti a questa domanda; la seguente funzione dividerà una stringa ( str) n-number ( size) di caratteri.
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>
La mia soluzione (sintassi ES6):
const source = "8d7f66a9273fc766cd66d1d";
const target = [];
for (
const array = Array.from(source);
array.length;
target.push(array.splice(0,2).join(''), 2));
Potremmo persino creare una funzione con questo:
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;
}
Quindi puoi chiamare facilmente la funzione in modo riutilizzabile:
const source = "8d7f66a9273fc766cd66d1d";
const target = splitStringBySegmentLength(source, 2);
Saluti
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, []);
Soluzione pulita senza REGEX
function chunk(er){
return er.match(/.{1,75}/g).join('\n');
}
La funzione sopra è quella che uso per il chunking Base64. Creerà un'interruzione di riga ogni 75 caratteri.
replace(/.{1,75}/g, '$&\n').
Qui intervalliamo una stringa con un'altra stringa ogni n caratteri:
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;
};
se utilizziamo quanto sopra in questo modo:
console.log(splitString(3,'|', 'aagaegeage'));
noi abbiamo:
AAG | AAG | AEG | eag | e
e qui facciamo lo stesso, ma spingiamo verso un 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;
};
e quindi eseguirlo:
console.log(sperseString(5, 'foobarbaztruck'));
noi abbiamo:
['fooba', 'rbazt', 'ruck']
se qualcuno conosce un modo per semplificare il codice sopra, lmk, ma dovrebbe funzionare bene per le stringhe.
Qualche soluzione pulita senza usare espressioni regolari:
/**
* 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;
};
Esempio di utilizzo - https://jsfiddle.net/maciejsikora/b6xppj4q/ .
Ho anche provato a confrontare la mia soluzione per regexp quella che è stata scelta come risposta giusta. Alcuni test sono disponibili su jsfiddle - https://jsfiddle.net/maciejsikora/2envahrk/ . I test stanno dimostrando che entrambi i metodi hanno prestazioni simili, forse a prima vista la soluzione regexp è un po 'più veloce, ma giudica te stesso.
Con .split:
var arr = str.split( /(?<=^(?:.{3})+)(?!$)/ ) // [ 'abc', 'def', 'ghi', 'jkl' ]
e .replacesarà:
var replaced = str.replace( /(?<=^(.{3})+)(?!$)/g, ' || ' ) // 'abc || def || ghi || jkl'
/(?!$)/è fermarsi prima della fine /$/, senza è:
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 || '
ignorare il gruppo /(?:... )/non è necessario .replacema in .splitsta aggiungendo gruppi ad arr:
var arr = str.split( /(?<=^(.{3})+)(?!$)/ ) // [ 'abc', 'abc', 'def', 'abc', 'ghi', 'abc', 'jkl' ]
Ecco un modo per farlo senza espressioni regolari o loop espliciti, anche se sta allungando un po 'la definizione di una riga:
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' ]
Funziona dividendo la stringa in una matrice di singoli caratteri, quindi usando Array.reduce per scorrere su ogni carattere. Normalmente reducerestituirebbe un singolo valore, ma in questo caso il singolo valore sembra essere un array, e mentre passiamo sopra ogni carattere lo aggiungiamo all'ultimo elemento in quell'array. Quando l'ultimo elemento dell'array raggiunge la lunghezza target, aggiungiamo un nuovo elemento dell'array.
Venendo un po 'più tardi alla discussione, ma qui una variazione che è un po' più veloce rispetto alla sottostringa + array push one.
// 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));
}
Il pre-calcolo del valore finale come parte del ciclo for è più veloce rispetto alla matematica inline all'interno della sottostringa. L'ho provato sia in Firefox che in Chrome ed entrambi mostrano una maggiore velocità.
Puoi provarlo qui