Réponses:
var str = 'abcdefghijkl';
console.log(str.match(/.{1,3}/g));
Remarque: utilisez {1,3}
au lieu de simplement {3}
pour inclure le reste pour les longueurs de chaîne qui ne sont pas un multiple de 3, par exemple:
console.log("abcd".match(/.{1,3}/g)); // ["abc", "d"]
Quelques subtilités supplémentaires:
.
ne les capturera pas. Utilisez /[\s\S]{1,3}/
plutôt. (Merci @Mike).match()
reviendra null
lorsque vous vous attendez à un tableau vide. Protégez-vous contre cela en ajoutant || []
.Vous pouvez donc vous retrouver avec:
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]
plutôt .
que pour ne pas échouer sur les nouvelles lignes.
''.match(/.{1,3}/g)
et ''.match(/.{3}/g)
revenez null
au lieu d'un tableau vide.
Si vous ne vouliez pas utiliser une expression régulière ...
var chunks = [];
for (var i = 0, charsLength = str.length; i < charsLength; i += 3) {
chunks.push(str.substring(i, i + 3));
}
jsFiddle .
... sinon la solution regex est plutôt bonne :)
3
variable est comme suggéré par l'OP. C'est plus lisible que de concaténer une chaîne d'expression régulière.
S'appuyant sur les réponses précédentes à cette question; la fonction suivante divisera une chaîne ( str
) n-nombre ( size
) de caractères.
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>
Ma solution (syntaxe ES6):
const source = "8d7f66a9273fc766cd66d1d";
const target = [];
for (
const array = Array.from(source);
array.length;
target.push(array.splice(0,2).join(''), 2));
Nous pourrions même créer une fonction avec ceci:
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;
}
Ensuite, vous pouvez appeler la fonction facilement de manière réutilisable:
const source = "8d7f66a9273fc766cd66d1d";
const target = splitStringBySegmentLength(source, 2);
À votre santé
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, []);
Solution propre sans REGEX
function chunk(er){
return er.match(/.{1,75}/g).join('\n');
}
La fonction ci-dessus est ce que j'utilise pour le découpage en Base64. Cela créera un saut de ligne de 75 caractères.
replace(/.{1,75}/g, '$&\n')
.
Ici, nous entrecoupons une chaîne avec une autre chaîne tous les n caractères:
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;
};
si nous utilisons ce qui précède ainsi:
console.log(splitString(3,'|', 'aagaegeage'));
on a:
aag | aag | aeg | eag | e
et ici nous faisons de même, mais poussons vers un tableau:
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;
};
puis exécutez-le:
console.log(sperseString(5, 'foobarbaztruck'));
on a:
['fooba', 'rbazt', 'ruck']
si quelqu'un connaît un moyen de simplifier le code ci-dessus, lmk, mais cela devrait fonctionner correctement pour les chaînes.
Une solution propre sans utiliser d'expressions régulières:
/**
* 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;
};
Exemple d'utilisation - https://jsfiddle.net/maciejsikora/b6xppj4q/ .
J'ai également essayé de comparer ma solution à l'expression rationnelle qui a été choisie comme bonne réponse. Un test peut être trouvé sur jsfiddle - https://jsfiddle.net/maciejsikora/2envahrk/ . Les tests montrent que les deux méthodes ont des performances similaires, peut-être qu'à première vue, la solution d'expression régulière est un peu plus rapide, mais jugez-en vous-même.
Avec .split
:
var arr = str.split( /(?<=^(?:.{3})+)(?!$)/ ) // [ 'abc', 'def', 'ghi', 'jkl' ]
et .replace
sera:
var replaced = str.replace( /(?<=^(.{3})+)(?!$)/g, ' || ' ) // 'abc || def || ghi || jkl'
/(?!$)/
est d'arrêter avant la fin /$/
, sans est:
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 || '
ignorer le groupe /(?:
... )/
n'est pas nécessaire dans .replace
mais .split
ajoute des groupes à arr:
var arr = str.split( /(?<=^(.{3})+)(?!$)/ ) // [ 'abc', 'abc', 'def', 'abc', 'ghi', 'abc', 'jkl' ]
Voici un moyen de le faire sans expressions régulières ni boucles explicites, bien qu'il étende un peu la définition d'une ligne:
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' ]
Il fonctionne en divisant la chaîne en un tableau de caractères individuels, puis en utilisant Array.reduce
pour itérer sur chaque caractère. Normalement, reduce
il retournerait une seule valeur, mais dans ce cas, la seule valeur se trouve être un tableau, et lorsque nous passons sur chaque caractère, nous l'ajoutons au dernier élément de ce tableau. Une fois que le dernier élément du tableau atteint la longueur cible, nous ajoutons un nouvel élément de tableau.
Venant un peu plus tard à la discussion, mais voici une variation un peu plus rapide que le push sous-chaîne + tableau.
// 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));
}
Le pré-calcul de la valeur finale dans le cadre de la boucle for est plus rapide que le calcul en ligne à l'intérieur de la sous-chaîne. Je l'ai testé à la fois dans Firefox et Chrome et ils montrent tous les deux une accélération.
Vous pouvez l'essayer ici