Javascript элегантный способ разбить строку на сегменты длиной n символов
как говорится в заголовке, у меня есть строка, и я хочу разделить на сегменты n символов.
например:
var str = 'abcdefghijkl';
после некоторого волшебства с n=3, станет
var arr = ['abc','def','ghi','jkl'];
есть ли элегантный способ сделать это?
9 ответов:
var str = 'abcdefghijkl'; console.log(str.match(/.{1,3}/g));Примечание: использовать просто
{3}чтобы включить остаток для длины строки, которая не кратна 3, например:console.log("abcd".match(/.{1,3}/g)); // ["abc", "d"]
еще пара тонкостей:
- если ваша строка может содержать символы новой строки (который вы хотите считать символом, а не разбивать строку), то
.не будет захватывать их. Используйте/[\s\S]{1,3}/вместо. (Спасибо @Майк).- если строка пуста, то
match()вернутсяnullкогда вы можете ожидать пустой массив. Защитите от этого, добавив|| []., так что вы можете в конечном итоге с:
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) || []);
Если вы не хотите использовать регулярное выражение...
var chunks = []; for (var i = 0, charsLength = str.length; i < charsLength; i += 3) { chunks.push(str.substring(i, i + 3)); }...в противном случае регулярное выражение решение довольно хорошо :)
основываясь на предыдущих ответах на этот вопрос; следующая функция разделит строку (
str) n-число (size) символов.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>
function chunk(er){ return er.match(/.{1,75}/g).join('\n'); }выше функция - это то, что я использую для base64 chunking. Это создаст разрыв строки когда-либо 75 символов.
мое решение (синтаксис ES6):
const source = "8d7f66a9273fc766cd66d1d"; const target = []; for ( const array = Array.from(source); array.length; target.push(array.splice(0,2).join(''), 2));мы могли бы даже создать функцию с этим:
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; }затем вы можете легко вызвать функцию повторно:
const source = "8d7f66a9273fc766cd66d1d"; const target = splitStringBySegmentLength(source, 2);Ура
чистое решение, без использования регулярных выражений:
/** * 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; };пример использования https://jsfiddle.net/maciejsikora/b6xppj4q/.
Я также попытался сравнить мое решение с регулярным выражением, которое было выбрано в качестве правильного ответа. Некоторые тесты можно найти на jsfiddle -https://jsfiddle.net/maciejsikora/2envahrk/. тесты показывают, что оба метода имеют одинаковую производительность, возможно, на первый взгляд регулярное выражение решение немного быстрее, но судить это ты сам.
вот быстрый двухстрочный, что запятые номера:
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]; }если бы он был разложен, это могло бы выглядеть так:
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; }во-первых, aryPart1 назначается с регулярным выражением, которое состоит из [от 0 до 2 чисел], а затем [строка символов, длина которых кратна 3], а затем [ноль или один нецифровый и все остальное].
затем, если это не "", мы добавляем [0 до 2 чисел] к aryChunks.
после этого берем [строку символов, длина которых кратна 3] и регулярное выражение сопоставляют их в массив [3-символьных частей] под названием aryPart2, который мы затем соединяем с aryChunks.
теперь aryChunks содержит куски, которые мы будем соединять с запятой и назначать outVal.
все, что осталось сделать, это добавить [ноль или одну нецифровую цифру и все остальное] к outVal и вернуть outVal вызывающему абоненту.
в OP, {0,2} и {3} в регулярном выражении 1 и {3} в регулярном выражении 2 может быть переменные, чтобы сделать куски любой длины, и \d в регулярных выражениях могут быть изменены на ".- если вы хотите, чтобы он работал не только с цифрами.
Я слишком долго писал это, так что может быть пара глюков. Укажи на них, и я их подправлю.
здесь мы перемежаем строку с другой строкой каждые n символов:
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; };если мы используем выше вот так:
console.log(splitString(3,'|', 'aagaegeage'));получаем:
aag|aag|aeg|eag / e
и здесь мы делаем то же самое, но нажать на массив:
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; };и затем запустить его:
console.log(sperseString(5, 'foobarbaztruck'));получаем:
['fooba', 'rbazt',' ruck']
если кто-то знает способ упростить выше код, lmk, но он должен работать нормально для строк.
Comments