特殊な文字列から配列を作成したい。形式は次のとおりです。
(a),(b),(c(d,e)),(f(g(h,i,j)))
配列は次のようになります。
(a) | (b) | (c(d,e)) | (f(g(h,i,j)))
このsplit()
関数を使用すると、次のような結果が得られるため、この関数を使用することはお勧めできません。
(a) | (b) | (c(d | e)) | (f(g(h | i | j)))
何か案は?
特殊な文字列から配列を作成したい。形式は次のとおりです。
(a),(b),(c(d,e)),(f(g(h,i,j)))
配列は次のようになります。
(a) | (b) | (c(d,e)) | (f(g(h,i,j)))
このsplit()
関数を使用すると、次のような結果が得られるため、この関数を使用することはお勧めできません。
(a) | (b) | (c(d | e)) | (f(g(h | i | j)))
何か案は?
考えられる短い解決策の 1 つを次に示します。
function strSplit(str, x) {
return x = 0, str.replace(/./g, function(c, i, a) {
return c === "(" ? (x++, c) :
c === ")" && i < a.length - 1 && --x === 0 ? c + "|" : c;
}).split("|,");
}
strSplit("(a),(b),(c(d,e)),(f(g(h,i,j),k(l,m),n))");
// >> ["(a)", "(b)", "(c(d,e))", "(f(g(h,i,j),k(l,m),n))"]
デモ: http://jsfiddle.net/WRdAC/
コードをより明確にするために、フルスケールのバリアントを次に示します。
function strSplit(str) {
var x = 0;
return str.replace(/./g, function(c, i, a) {
if (c === "(") {
x++;
} else if (c === ")" && i < a.length - 1 && --x === 0) {
return c + "|";
}
return c;
}).split("|,");
}
開き括弧の数を数えてみませんか?カウントがゼロの場合、安全に分割できます。
var
input = '(a),(b),(c(d,e)),(f(g(h,i,j)))',
i = 0,
lim = input.length,
output = [],
count = 0,
stack = [],
c;
for (; i < lim; i += 1) {
c = input.charAt(i);
switch (c) {
case '(':
count += 1;
break;
case ')':
count -= 1;
break;
case ',':
if (count === 0) {
output.push(stack.join(''));
stack = [];
continue;
}
break;
}
stack.push(c);
}
if (stack.length > 0) {
output.push(stack.join(''));
}
console.log(output); // ["(a)", "(b)", "(c(d,e))", "(f(g(h,i,j)))"]
または代わりに (IE < 9 を対象としていない場合):
function mySplit(input) {
var count = 0, output = [], stack;
stack = input.split('').reduce(function (stack, c) {
switch (c) {
case '(': count += 1; break;
case ')': count -= 1; break;
case ',':
if (count === 0) {
output.push(stack.join(''));
return [];
}
}
stack.push(c);
return stack;
}, []);
if (stack.length > 0) {
output.push(stack.join(''));
}
return output;
}
console.log( mySplit('(a),(b),(c(d,e)),(f(g(h,i,j)))') );
このようなもの:
var s = "(a),(b),(c(d,e)),(f(g(h,i,j)))";
var a = s.split("),");
for (var i = 0; i < a.length - 1; i++)
a[i] = a[i] + ")";
より複雑な構造では、これが必要になる場合があります。
var s = "(a),(b),(c(d,e)),(f(g(h,i,j),k(l,m),n))";
var a = s.split("),(");
for (var i = 0; i < a.length - 1; i++)
a[i] = a[i] + ")";
for (var i = 1; i < a.length; i++)
a[i] = "(" + a[i];
この関数はまさにあなたが探していることを行います:
function parseStrToArr(str){
var pairs = 0;
var arr = [];
var chars = '';
for(var i = 0, l = str.length; i < l; i++){
var char = str[i];
switch(char){
case '(': pairs++; break;
case ')': pairs--; break;
}
if(!pairs){
if(chars){
arr.push(chars + char);
chars = '';
}
}
else{
chars += char;
}
}
return arr;
}
重要なのは、括弧のペアを一致させることです。このアルゴリズムは、コンマを削除しても機能します。