Respuestas:
var str = 'abcdefghijkl';
console.log(str.match(/.{1,3}/g));
Nota: Use en {1,3}
lugar de solo {3}
incluir el resto para las longitudes de cadena que no son múltiplos de 3, por ejemplo:
console.log("abcd".match(/.{1,3}/g)); // ["abc", "d"]
Un par de sutilezas más:
.
no las capturará. Usar en su /[\s\S]{1,3}/
lugar. (Gracias @ Mike).match()
volverá null
cuando espere una matriz vacía. Protéjase contra esto agregando || []
.Entonces puede terminar 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]
lugar de .
no fallar en las nuevas líneas.
''.match(/.{1,3}/g)
y ''.match(/.{3}/g)
regresar en null
lugar de una matriz vacía.
Si no quieres usar una expresión regular ...
var chunks = [];
for (var i = 0, charsLength = str.length; i < charsLength; i += 3) {
chunks.push(str.substring(i, i + 3));
}
jsFiddle .
... de lo contrario, la solución regex es bastante buena :)
3
variable es la sugerida por el OP. Es más legible que concatenar una cadena regexp.
Partiendo de las respuestas anteriores a esta pregunta; la siguiente función dividirá una cadena ( str
) n-número ( size
) de caracteres.
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>
Mi solución (sintaxis ES6):
const source = "8d7f66a9273fc766cd66d1d";
const target = [];
for (
const array = Array.from(source);
array.length;
target.push(array.splice(0,2).join(''), 2));
Incluso podríamos crear una función con esto:
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;
}
Luego puede llamar a la función fácilmente de manera reutilizable:
const source = "8d7f66a9273fc766cd66d1d";
const target = splitStringBySegmentLength(source, 2);
Salud
function chunk(er){
return er.match(/.{1,75}/g).join('\n');
}
La función anterior es lo que uso para la fragmentación de Base64. Creará un salto de línea cada 75 caracteres.
replace(/.{1,75}/g, '$&\n')
.
Aquí entremezclamos una cadena con otra cadena cada n caracteres:
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 usamos lo anterior así:
console.log(splitString(3,'|', 'aagaegeage'));
obtenemos:
aag | aag | aeg | eag | e
y aquí hacemos lo mismo, pero empujamos a una matriz:
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;
};
y luego ejecutarlo:
console.log(sperseString(5, 'foobarbaztruck'));
obtenemos:
['fooba', 'rbazt', 'ruck']
si alguien conoce una manera de simplificar el código anterior, lmk, pero debería funcionar bien para las cadenas.
Alguna solución limpia sin usar expresiones regulares:
/**
* 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;
};
Ejemplo de uso: https://jsfiddle.net/maciejsikora/b6xppj4q/ .
También intenté comparar mi solución para regexp una que fue elegida como respuesta correcta. Algunas pruebas se pueden encontrar en jsfiddle - https://jsfiddle.net/maciejsikora/2envahrk/ . Las pruebas muestran que ambos métodos tienen un rendimiento similar, tal vez a primera vista la solución regexp es un poco más rápida, pero juzgue usted mismo.
Con .split
:
var arr = str.split( /(?<=^(?:.{3})+)(?!$)/ ) // [ 'abc', 'def', 'ghi', 'jkl' ]
y .replace
será:
var replaced = str.replace( /(?<=^(.{3})+)(?!$)/g, ' || ' ) // 'abc || def || ghi || jkl'
/(?!$)/
es detenerse antes de finalizar /$/
, sin es:
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 || '
ignorar el grupo /(?:
... )/
no es necesario, .replace
pero en .split
agregar grupos al arr:
var arr = str.split( /(?<=^(.{3})+)(?!$)/ ) // [ 'abc', 'abc', 'def', 'abc', 'ghi', 'abc', 'jkl' ]
Aquí hay una manera de hacerlo sin expresiones regulares o bucles explícitos, aunque está ampliando un poco la definición de un trazador de líneas:
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' ]
Funciona al dividir la cadena en una matriz de caracteres individuales, luego se usa Array.reduce
para iterar sobre cada carácter. Normalmente reduce
devolvería un valor único, pero en este caso el valor único es una matriz y, a medida que pasamos por encima de cada carácter, lo agregamos al último elemento de esa matriz. Una vez que el último elemento de la matriz alcanza la longitud objetivo, agregamos un nuevo elemento de matriz.
Llegando un poco más tarde a la discusión, pero aquí hay una variación que es un poco más rápida que la subcadena + matriz 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));
}
El cálculo previo del valor final como parte del ciclo for es más rápido que hacer las matemáticas en línea dentro de la subcadena. Lo probé tanto en Firefox como en Chrome y ambos muestran aceleración.
Puedes probarlo aquí