4 回答

TA貢獻1808條經(jīng)驗 獲得超4個贊
您可以創(chuàng)建自己的解析器,并跟蹤“堆棧”以檢測之前是否打開了括號。下面的示例適用于()、[]、{}或您想要的任何內(nèi)容。它們可以相互嵌套。
你可以像這樣使用它:
const mySplit = customSplitFactory({
delimiter: ',',
escapedPairs: {
'(': ')',
'{': '}',
'[': ']'
}
});
mySplit('one, two, start (a, b) end'); // ["one"," two"," start (a, b) end"]
代碼和演示:
// Generic factory function
function customSplitFactory({ delimiter, escapedPairs }) {
const escapedStartChars = Object.keys(escapedPairs);
return (str) => {
const result = str.split('')
// For each character
.reduce((res, char) => {
// If it's a start escape char `(`, `[`, ...
if (escapedStartChars.includes(char)) {
// Add the corresponding end char to the stack
res.escapeStack.push(escapedPairs[char]);
// Add the char to the current group
res.currentGroup.push(char);
// If it's the end escape char we were waiting for `)`, `]`, ...
} else if (
res.escapeStack.length &&
char === res.escapeStack[res.escapeStack.length - 1]
) {
// Remove it from the stack
res.escapeStack.pop();
// Add the char to the current group
res.currentGroup.push(char);
// If it's a delimiter and the escape stack is empty
} else if (char === delimiter && !res.escapeStack.length) {
if (res.currentGroup.length) {
// Push the current group into the results
res.groups.push(res.currentGroup.join(''));
}
// Reset it
res.currentGroup = [];
} else {
// Otherwise, just push the char into the current group
res.currentGroup.push(char);
}
return res;
}, {
groups: [],
currentGroup: [],
escapeStack: []
});
// If the current group was not added to the results yet
if (result.currentGroup.length) {
result.groups.push(result.currentGroup.join(''));
}
return result.groups;
};
}
// Usage
const mySplit = customSplitFactory({
delimiter: ',',
escapedPairs: {
'(': ')',
'{': '}',
'[': ']'
}
});
function demo(s) { // Just for this demo
const res = mySplit(s);
console.log([s, res].map(JSON.stringify).join(' // '));
}
demo('one, two, start (a, b) end,'); // ["one"," two"," start (a, b) end"]
demo('one, two, start {a, b} end'); // ["one"," two"," start {a, b} end"]
demo('one, two, start [{a, b}] end,'); // ["one"," two"," start [{a, b}] end"]
demo('one, two, start ((a, b)) end,'); // ["one"," two"," start ((a, b)) end"]

TA貢獻2011條經(jīng)驗 獲得超2個贊
您需要首先考慮特殊情況,即括號,首先處理它:
var str, mtc;
str = "one, two, start (a, b) end, hello";
mtc = str.match(/[^,]*\([^\)]+\)[^,]+|[^,]+/g);
console.log(mtc);
//Expected output: ["one","two", " start (a, b) end", " hello"]
首先,處理括號:
patt = /[^,]*\([^\)]+\)[^,]+/g
//That will match any character after ,
//Then match character "(" and then match any charecter with no ")" then ends with )
//Now is easy things, we just matches character withno colon
patt = /[^,]+/g

TA貢獻1829條經(jīng)驗 獲得超7個贊
正如一些評論所建議的,您可以使用 split 功能。例子:
let str = "one, two, start (a, b) end,"; let matches = str.split(/(?<!(\"|\{|\()[a-zA-Z0-9]*),(?![a-zA-Z0-9]*\)|\}|\")/);
match 將是一個包含 ["one", "two", "start (a, b) end", "" ] 的數(shù)組;
文檔:https ://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split

TA貢獻1793條經(jīng)驗 獲得超6個贊
如果不需要處理不匹配的大括號,則可以將其簡化為天真的平衡大括號計數(shù)器。
目前使用默認正常文本盡力而為:
如果檢測到右大括號,它將嘗試找到起始大括號并將其括起來,將封閉的段視為文本
如果沒有找到起始大括號,則將其視為普通文本
const braces = {'{':'}','[':']','(':')'}
// create object map of ending braces to starting braces
const inv_braces = Object.fromEntries(Object.entries(braces).map(x=>x.reverse()))
const red = new RegExp(`(,)|` +
`([${Object.keys(braces).join('')}])|` +
`([${Object.values(braces).map(x=>`\\${x}`).join('')}])` , 'g')
// pre-build break-point scanning regexes
// group1 comma detection, group2 start braces, group3 end braces
element_extract= str => {
let res = []
let stack = [], next, last = -1
// search until no more break-points found
while(next = red.exec(str)) {
const [,comma,begin,end] = next, {index} = next
if(begin) stack.push(begin) // beginning brace, push to stack
else if(end){ //ending brace, pop off stack to starting brace
const start = stack.lastIndexOf(inv_braces[end])
if(start!==-1) stack.length = start
}
else if(!stack.length && comma) res.push(str.slice(last+1,last=index))
// empty stack and comma, slice string and push to results
}
if(last<str.length) res.push(str.slice(last+1)) // final element
return res
}
data = [
"one, two, start (a, b) end",
"one, two, start ((a, (b][,c)]) ((d,e),f)) end, two",
"one, two ((a, (b,c)) ((d,e),f)) three, start (a, (b,c)) ((d,e),f) end, four",
"(a, (b,c)) ((d,e)],f))"
]
for(const x of data)
console.log(element_extract(x))
筆記:
可以通過為 \ 添加另一個匹配組并增加索引以跳過來添加轉(zhuǎn)義
可以添加正則表達式字符串清理器以允許匹配特殊字符
可以添加第二個正則表達式以跳過逗號進行優(yōu)化(請參閱編輯歷史記錄)
可以通過替換逗號匹配器并在計算中包括定界符長度來添加對可變長度定界符的支持。大括號也是如此。
例如,我可以使用 (\s*,\s*) 而不是 (,) 來去除空格,或者通過調(diào)整正則表達式生成器以使用 '|' 來使用 '{{':'}}' 作為大括號 而不是字符類
為簡單起見,我省略了這些
添加回答
舉報