タイトルにあるように、文字列があり、セグメントに分割したいn文字長。
例えば:
var str = 'abcdefghijkl';
n = 3の魔法の後、
var arr = ['abc','def','ghi','jkl'];
これを行うエレガントな方法はありますか?
var str = 'abcdefghijkl';
console.log(str.match(/.{1,3}/g));
注:{1,3}
の代わりに{3}
を使用して、3の倍数ではない文字列の長さの残りを含めます。例:
console.log("abcd".match(/.{1,3}/g)); // ["abc", "d"]
さらにいくつかの微妙な点:
.
はそれらをキャプチャします。代わりに/[\s\S]{1,3}/
を使用してください。 (@Mikeに感謝)。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));
}
jsFiddle 。
...そうでなければ、正規表現のソリューションはかなり良いです:)
str.match(/.{3}/g); // => ['abc', 'def', 'ghi', 'jkl']
この質問に対する以前の回答に基づいて作成します。次の関数は、文字列(str
)の文字数(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>
私の解決策(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);
乾杯
function chunk(er){
return er.match(/.{1,75}/g).join('\n');
}
上記の関数は、Base64チャンクに使用するものです。 75文字までの改行が作成されます。
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, []);
REGEXを使用しないクリーンなソリューション
ここでは、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を単純化する方法を知っていれば、それは文字列に対してはうまくいくはずです。
正規表現を使用しないクリーンなソリューション:
/**
* 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/ 。テストでは、両方のメソッドのパフォーマンスが似ていることが示されています。一見すると、正規表現ソリューションは少し高速ですが、自分で判断してください。
.split
を使用:
var arr = str.split( /(?<=^(?:.{3})+)(?!$)/ ) // [ 'abc', 'def', 'ghi', 'jkl' ]
および.replace
は次のようになります。
var replaced = str.replace( /(?<=^(.{3})+)(?!$)/g, ' || ' ) // 'abc || def || ghi || jkl'
/(?!$)/
は、end/$/
の前に停止することです。
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 || '
グループを無視/(?:
...)/
は.replace
では不要ですが、.split
ではarrにグループを追加しています:
var arr = str.split( /(?<=^(.{3})+)(?!$)/ ) // [ 'abc', 'abc', 'def', 'abc', 'ghi', 'abc', 'jkl' ]
数字をカンマで囲む簡単な2ライナーを次に示します。
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の倍数の文字列]、[ゼロまたは1桁の非数字およびその他すべて]が続きます。
次に、 ""でない場合、[0〜2の数字]をaryChunksに追加します。
その後、[長さが3の倍数である文字列]を取得し、正規表現をaryPart2と呼ばれる[3文字の断片]の配列に一致させてから、aryChunksに接続します。
AryChunksには、カンマで結合してoutValに割り当てるチャンクが含まれています。
あとは、[ゼロまたは1つの非数字とその他すべて]をoutValに追加し、発信者にoutValを返すだけです。
OPごとに、正規表現1の{0,2}と{3}および正規表現2の{3}は、チャンクを任意の長さにする変数にすることができ、正規表現の\ dは "。"に変更できます。数字だけでなくそれ以上の機能が必要な場合。
私はこれを書くのに長すぎたので、いくつかの不具合があるかもしれません。指摘し、微調整します。