Antworten:
var str = 'abcdefghijkl';
console.log(str.match(/.{1,3}/g));
Hinweis: Verwenden Sie {1,3}
statt nur {3}
, um den Rest für Zeichenfolgenlängen einzuschließen, die kein Vielfaches von 3 sind, z.
console.log("abcd".match(/.{1,3}/g)); // ["abc", "d"]
Noch ein paar Feinheiten:
.
werden diese nicht erfasst. Verwenden Sie /[\s\S]{1,3}/
stattdessen. (Danke @Mike).match()
wird sie zurückgegeben, null
wenn Sie möglicherweise ein leeres Array erwarten. Schützen Sie sich davor durch Anhängen || []
.So können Sie am Ende mit:
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]
stattdessen, .
um bei Zeilenumbrüchen nicht zu versagen.
''.match(/.{1,3}/g)
und das ''.match(/.{3}/g)
Rück null
anstelle eines leeren Array.
Wenn Sie keinen regulären Ausdruck verwenden möchten ...
var chunks = [];
for (var i = 0, charsLength = str.length; i < charsLength; i += 3) {
chunks.push(str.substring(i, i + 3));
}
jsFiddle .
... sonst ist die Regex-Lösung ziemlich gut :)
3
Variable vom OP vorgeschlagen wird. Es ist besser lesbar als eine Regexp-Zeichenfolge zu verketten.
Aufbauend auf den vorherigen Antworten auf diese Frage; Die folgende Funktion teilt eine Zeichenfolge ( str
) n-Anzahl ( size
) von Zeichen.
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>
Meine Lösung (ES6-Syntax):
const source = "8d7f66a9273fc766cd66d1d";
const target = [];
for (
const array = Array.from(source);
array.length;
target.push(array.splice(0,2).join(''), 2));
Wir könnten sogar eine Funktion damit erstellen:
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;
}
Dann können Sie die Funktion einfach und wiederverwendbar aufrufen:
const source = "8d7f66a9273fc766cd66d1d";
const target = splitStringBySegmentLength(source, 2);
Prost
function chunk(er){
return er.match(/.{1,75}/g).join('\n');
}
Die obige Funktion verwende ich für Base64-Chunking. Es wird ein Zeilenumbruch von jeweils 75 Zeichen erstellt.
replace(/.{1,75}/g, '$&\n')
.
Hier durchsetzen wir alle n Zeichen eine Zeichenfolge mit einer anderen Zeichenfolge:
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;
};
wenn wir das obige wie folgt verwenden:
console.log(splitString(3,'|', 'aagaegeage'));
wir bekommen:
aag | aag | aeg | eag | e
und hier machen wir dasselbe, aber drücken auf ein 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;
};
und dann ausführen:
console.log(sperseString(5, 'foobarbaztruck'));
wir bekommen:
['fooba', 'rbazt', 'ruck']
Wenn jemand eine Möglichkeit kennt, den obigen Code zu vereinfachen, lmk, aber es sollte gut für Zeichenfolgen funktionieren.
Eine saubere Lösung ohne reguläre Ausdrücke:
/**
* 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;
};
Anwendungsbeispiel - https://jsfiddle.net/maciejsikora/b6xppj4q/ .
Ich habe auch versucht, meine Lösung mit einer regulären zu vergleichen, die als richtige Antwort ausgewählt wurde. Einige Tests finden Sie auf jsfiddle - https://jsfiddle.net/maciejsikora/2envahrk/ . Tests zeigen, dass beide Methoden eine ähnliche Leistung haben. Vielleicht ist die Regexp-Lösung auf den ersten Blick etwas schneller, aber beurteilen Sie es selbst.
Mit .split
:
var arr = str.split( /(?<=^(?:.{3})+)(?!$)/ ) // [ 'abc', 'def', 'ghi', 'jkl' ]
und .replace
wird sein:
var replaced = str.replace( /(?<=^(.{3})+)(?!$)/g, ' || ' ) // 'abc || def || ghi || jkl'
/(?!$)/
ist vor dem Ende anzuhalten /$/
, ohne ist:
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 || '
Gruppe ignorieren /(?:
... )/
ist nicht erforderlich, .replace
aber in .split
fügt Gruppen zu arr hinzu:
var arr = str.split( /(?<=^(.{3})+)(?!$)/ ) // [ 'abc', 'abc', 'def', 'abc', 'ghi', 'abc', 'jkl' ]
Hier ist eine Möglichkeit, dies ohne reguläre Ausdrücke oder explizite Schleifen zu tun, obwohl dadurch die Definition eines Einzeilers ein wenig erweitert wird:
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' ]
Es funktioniert, indem die Zeichenfolge in ein Array einzelner Zeichen aufgeteilt und dann Array.reduce
über jedes Zeichen iteriert wird. Normalerweise reduce
würde ein einzelner Wert zurückgegeben, aber in diesem Fall ist der einzelne Wert zufällig ein Array, und wenn wir über jedes Zeichen gehen, hängen wir es an das letzte Element in diesem Array an. Sobald das letzte Element im Array die Ziellänge erreicht hat, fügen wir ein neues Arrayelement hinzu.
Kommen wir etwas später zur Diskussion, aber hier eine Variation, die etwas schneller ist als die Teilzeichenfolge + 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));
}
Die Vorberechnung des Endwerts als Teil der for-Schleife ist schneller als die Inline-Berechnung innerhalb des Teilstrings. Ich habe es sowohl in Firefox als auch in Chrome getestet und beide zeigen eine Beschleunigung.
Sie können es hier versuchen