This question already has an answer here:
这个问题在这里已有答案:
- Split string in JavaScript using RegExp ignoring the delimiter inside brackets 2 answers
- 使用RegExp在JavaScript中拆分字符串,忽略括号内的分隔符2个答案
I want to split a string by commas, but not when they're inside brackets.
我想用逗号分隔一个字符串,但不是当它们在括号内时。
For instance:
例如:
"[1, '15', [false]], [[], 'sup']"
would split into
会分裂成
[
"[1, '15', [false]]",
"[[], 'sup']"
]
I've tried /\,(?=(.*\[.*\])*.*\]{1})/
for my regexp, my logic is match commas that aren't followed by an even number of '[]' with any characters in between and outside followed by one ']'.
我已经尝试了/\,(?=(。*。[*。*])*。*。{}} /)对于我的正则表达式,我的逻辑是匹配逗号,后面没有偶数个' []'中间和外部的任何字符后跟一个']'。
3 个解决方案
#1
2
If expected result are two strings, irrespective of whether or not strings are parseable as javascript
object or valid JSON
you can use Array.prototype.reduce()
, String.prototype.split()
, String.prototype.replace()
如果预期结果是两个字符串,无论字符串是否可解析为javascript对象或有效JSON,您都可以使用Array.prototype.reduce(),String.prototype.split(),String.prototype.replace()
var str = "[1, '15', [false]], [[], 'sup']";
var res = str.split(/,/).reduce((arr, text) => {
text = text.trim();
if (arr.length === 0) {
arr.push([]);
}
if (/^\[/.test(text) && !/\]$/.test(text)) {
arr[arr.length === 1 ? 0 : arr.length - 1].push(text.slice(1));
return arr
}
if (!/^\[/.test(text) && /\]$/.test(text)) {
arr[arr.length === 1 ? 0 : arr.length - 1].push(text.slice(0, -1));
return arr
}
if (!/^\[/.test(text) && !/\]$/.test(text)
|| /^\[/.test(text) && /\]{2}$/.test(text)
|| !/\[|\]/.test(text)) {
arr[arr.length === 1 ? 0 : arr.length - 1].push(text);
return arr
}
if (/^\[{2}/.test(text) && /\]$/.test(text)) {
arr[arr.length - 1].push(text);
return arr
}
return arr
}, []);
var strs = `[${res.join()}]`.replace(/"/g, "").split(/,(?=\[{2})|"(?=")/);
console.log(`str1:${strs[0]}\nstr2:${strs[1]}`);
#2
1
Regexp is not well-suited to situations like this involving nesting. You might want to write a tiny parser:
Regexp不适合这种涉及嵌套的情况。您可能想要编写一个小解析器:
function parse(str) {
let result = [], item = '', depth = 0;
function push() { if (item) result.push(item); item = ''; }
for (let i = 0, c; c = str[i], i < str.length; i++) {
if (!depth && c === ',') push();
else {
item += c;
if (c === '[') depth++;
if (c === ']') depth--;
}
}
push();
return result;
}
console.log(parse("[1, '15', [false]], [[], 'sup']"));
You may want to tweak this to handle spaces around the commas, unbalanced square brackets, etc.
您可能需要调整它以处理逗号,不平衡方括号等周围的空格。
#3
0
If string is proper array-like string... maybe this is worth a try, too:
如果string是正确的类似数组的字符串...也许这也值得一试:
var regex = /(\[.*?\]\])|(\[\[.*?\]$)|(\[(.*?)\])|(,)/gm;
var regex = /(\[.*?\]\])|(\[\[.*?\]$)|(\[(.*?)\])|(,)/gm;
str = "[1, '15', [false]], [[], 'sup']";
/*str="[1, [30] [false][,]], [[]false, 'sup'[]]";
str="[[] []], [1,4,5[8]]";
str="[[1,2,3],[3,6,7]],[[],566,[]]";
str="[[],[]],['duh,[],'buh',[]]";
str="[1,2,3],[5,'ggg','h']"*/
arr=[];
while ((matches = regex.exec(str)) !== null) {
if(matches[0]!==',')
arr.push(matches[0]);
}
console.log(arr);
So, basically, match alternative groups, loop through results, keep non-comma matches. This will fail, probably, in some cases...but, should be tested more.
所以,基本上,匹配替代组,循环结果,保持非逗号匹配。在某些情况下,这可能会失败......但是,应该进行更多测试。
#1
2
If expected result are two strings, irrespective of whether or not strings are parseable as javascript
object or valid JSON
you can use Array.prototype.reduce()
, String.prototype.split()
, String.prototype.replace()
如果预期结果是两个字符串,无论字符串是否可解析为javascript对象或有效JSON,您都可以使用Array.prototype.reduce(),String.prototype.split(),String.prototype.replace()
var str = "[1, '15', [false]], [[], 'sup']";
var res = str.split(/,/).reduce((arr, text) => {
text = text.trim();
if (arr.length === 0) {
arr.push([]);
}
if (/^\[/.test(text) && !/\]$/.test(text)) {
arr[arr.length === 1 ? 0 : arr.length - 1].push(text.slice(1));
return arr
}
if (!/^\[/.test(text) && /\]$/.test(text)) {
arr[arr.length === 1 ? 0 : arr.length - 1].push(text.slice(0, -1));
return arr
}
if (!/^\[/.test(text) && !/\]$/.test(text)
|| /^\[/.test(text) && /\]{2}$/.test(text)
|| !/\[|\]/.test(text)) {
arr[arr.length === 1 ? 0 : arr.length - 1].push(text);
return arr
}
if (/^\[{2}/.test(text) && /\]$/.test(text)) {
arr[arr.length - 1].push(text);
return arr
}
return arr
}, []);
var strs = `[${res.join()}]`.replace(/"/g, "").split(/,(?=\[{2})|"(?=")/);
console.log(`str1:${strs[0]}\nstr2:${strs[1]}`);
#2
1
Regexp is not well-suited to situations like this involving nesting. You might want to write a tiny parser:
Regexp不适合这种涉及嵌套的情况。您可能想要编写一个小解析器:
function parse(str) {
let result = [], item = '', depth = 0;
function push() { if (item) result.push(item); item = ''; }
for (let i = 0, c; c = str[i], i < str.length; i++) {
if (!depth && c === ',') push();
else {
item += c;
if (c === '[') depth++;
if (c === ']') depth--;
}
}
push();
return result;
}
console.log(parse("[1, '15', [false]], [[], 'sup']"));
You may want to tweak this to handle spaces around the commas, unbalanced square brackets, etc.
您可能需要调整它以处理逗号,不平衡方括号等周围的空格。
#3
0
If string is proper array-like string... maybe this is worth a try, too:
如果string是正确的类似数组的字符串...也许这也值得一试:
var regex = /(\[.*?\]\])|(\[\[.*?\]$)|(\[(.*?)\])|(,)/gm;
var regex = /(\[.*?\]\])|(\[\[.*?\]$)|(\[(.*?)\])|(,)/gm;
str = "[1, '15', [false]], [[], 'sup']";
/*str="[1, [30] [false][,]], [[]false, 'sup'[]]";
str="[[] []], [1,4,5[8]]";
str="[[1,2,3],[3,6,7]],[[],566,[]]";
str="[[],[]],['duh,[],'buh',[]]";
str="[1,2,3],[5,'ggg','h']"*/
arr=[];
while ((matches = regex.exec(str)) !== null) {
if(matches[0]!==',')
arr.push(matches[0]);
}
console.log(arr);
So, basically, match alternative groups, loop through results, keep non-comma matches. This will fail, probably, in some cases...but, should be tested more.
所以,基本上,匹配替代组,循环结果,保持非逗号匹配。在某些情况下,这可能会失败......但是,应该进行更多测试。