wake-up-neo.com

Javascript-elegante Möglichkeit, Zeichenfolge in Segmente mit einer Länge von n Zeichen aufzuteilen

Wie der Titel sagt, habe ich eine Zeichenfolge und möchte in Segmente n Zeichen Länge teilen.

Zum Beispiel:

var str = 'abcdefghijkl';

nach etwas Magie mit n = 3 wird es werden

var arr = ['abc','def','ghi','jkl'];

Gibt es eine elegante Möglichkeit, dies zu tun?

144
Ben
var str = 'abcdefghijkl';
console.log(str.match(/.{1,3}/g));

Hinweis: Verwenden Sie {1,3} anstelle von {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:

  1. Wenn Ihre Zeichenfolge möglicherweise Zeilenumbrüche enthält, die Sie als Zeichen zählen möchten, anstatt die Zeichenfolge zu teilen , wird der . nicht verwendet fang die ein. Verwenden Sie stattdessen /[\s\S]{1,3}/. (Danke @Mike).
  2. Wenn Ihre Zeichenfolge leer ist, gibt match()null zurück, wenn Sie möglicherweise ein leeres Array erwarten. Schützen Sie sich davor, indem Sie || [] 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) || []);
308
David Tang

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 :)

34
alex
str.match(/.{3}/g); // => ['abc', 'def', 'ghi', 'jkl']
19
maerics

Aufbauend auf den vorherigen Antworten auf diese Frage; Die folgende Funktion teilt eine Zeichenfolge (str) n-Nummer (size) von Zeichen auf.

function chunk(str, size) {
    return str.match(new RegExp('.{1,' + size + '}', 'g'));
}

Demo

(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>

8
Mr. Polywhirl
function chunk(er){
return er.match(/.{1,75}/g).join('\n');
}

Die obige Funktion verwende ich für das Base64-Chunking. Es wird ein Zeilenumbruch mit 75 Zeichen erstellt.

1
Dave Brown
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, []);

Saubere Lösung ohne REGEX

1
seriouspat

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 damit sogar eine Funktion 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 wiederverwendbar aufrufen:

const source = "8d7f66a9273fc766cd66d1d";
const target = splitStringBySegmentLength(source, 2);

Prost

1
Jesus Gonzalez

Einige 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 zu vergleichen, um eine auszudrücken, die als richtige Antwort gewählt wurde. Einige Tests finden Sie unter jsfiddle - https://jsfiddle.net/maciejsikora/2envahrk/ . Tests zeigen, dass beide Methoden eine ähnliche Leistung aufweisen. Auf den ersten Blick scheint die reguläre Lösung etwas schneller zu sein, aber beurteilen Sie es selbst.

0
Maciej Sikora

Hier streuen wir alle n Zeichen einen String mit einem anderen String:

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 die oben genannten so verwenden:

console.log(splitString(3,'|', 'aagaegeage'));

wir bekommen:

aag | aag | aeg | eag | e

und hier machen wir dasselbe, aber drücken Sie 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 führe es aus:

console.log(sperseString(5, 'foobarbaztruck'));

wir bekommen:

['fooba', 'rbazt', 'ruck']

wenn jemand eine Möglichkeit zur Vereinfachung des obigen Codes kennt, lmk, sollte dies jedoch für Strings problemlos funktionieren.

0
Alexander Mills

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'



/(?!$)/ soll vor end/$/ anhalten, 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 || '

das Ignorieren der Gruppe /(?:...)/ ist in .replace nicht erforderlich, aber in .split werden Gruppen zu arr hinzugefügt:

var arr = str.split( /(?<=^(.{3})+)(?!$)/ )  // [ 'abc', 'abc', 'def', 'abc', 'ghi', 'abc', 'jkl' ]

Hier ist ein schneller Two-Liner, der Zahlen kommuniziert:

function commafy(inVal){
    var ary = String(inVal).match(/(\d{0,2})((?:\d{3})*)([^\d].*$)/i);
    return (ary[1] == "" ? [] : [ary[1]]).splice(1, 0, ary[2].match(/[0-9]{3}/g)).join(",") + ary[3];
}

wenn es verteilt wäre, könnte es so aussehen:

function commafy(inVal){
    var aryChunks = [];
    var inVal = String(inVal);
    var aryPart1 = inVal.match(/(\d{0,2})((?:\d{3})*)([^\d].*$)/i);
    if(aryPart1[1] != ""){
        aryChunks.Push(aryPart1[1]);
    }
    var aryPart2 = aryPart1[2].match(/[0-9]{3}/g);
    aryChunks.splice(1, 0, aryPart2);
    var outVal = aryChunks.join(",");
    outVal += aryPart1[3];
    return outVal;
}

Zunächst wird aryPart1 eine Regex-Übereinstimmung zugewiesen, die aus [0 bis 2 Zahlen] besteht, gefolgt von [Zeichenfolge aus Zeichen, deren Länge ein Vielfaches von 3 ist] und dann [null oder eine Nicht-Ziffer und alles andere].

Wenn es nicht "" ist, hängen wir die [0 bis 2-Nummern] an aryChunks an. 

Danach nehmen wir die Zeichenfolge [Zeichenfolge, deren Länge ein Vielfaches von 3 ist] und passen sie mit einem regulären Ausdruck in ein Array von [3-stelligen Stücken] namens aryPart2 ein, das wir dann zu aryChunks zusammenfügen.

Nun enthält aryChunks die Chunks, die wir mit einem Komma verbinden und outVal zuweisen.

Jetzt müssen Sie nur noch [null oder eine Nicht-Ziffer und alles andere] an outVal anhängen und an den Anrufer zurückgeben.

Je nach OP können die {0,2} und {3} in Regex 1 und {3} in Regex 2 Variablen sein, um die Chunks beliebig lang zu machen, und das\d in den Regex kann in "." Geändert werden. Wenn Sie möchten, dass mehr als nur Zahlen verarbeitet werden.

Ich habe viel zu lange damit verbracht, das aufzuschreiben, daher könnte es ein paar Störungen geben. Zeig sie raus und ich werde sie zwicken.

0
alfadog67