2016-10-26 3 views
0

Я хотел бы написать регулярное выражение, которое разделяет строку запятыми, которые не являются внутри().Разделить строку символами, которые не находятся внутри определенной границы

Примеры:

"test,test,test".split(/.../) => var a = ["test", "test", "test"]; 
"test(123,345),test".split(/.../) => var a = ["test(123,345)", "test"]; 
"test(123,345),a(b,c)".split(/.../) => var a = ["test(123,345)", "a(b,c)"]; 
"test(cb(a,b),345),a(b(d,e,f),c),abc".split(/.../) => var a = ["test(cb(a,b),345)", "a(b(d,e,f),c)", "abc"]; 

У меня есть следующее регулярное выражение, но это работает только, если у меня нет() после первого матча запятой:

"test,test,test".split(/,(?!.*\))/) => OK 
"test(cb(a,b),345),test,test".split(/,(?!.*\))/) => OK 
"test,test(cb(a,b),345),test".split(/,(?!.*\))/) => FAIL 
+0

Возможно, '/, (?! [^,] * \)) /'? –

ответ

2

Регулярные выражения не приспособленного к этой задаче. Я думаю, было бы проще свернуть свой собственный парсер, где вы следуете уровню кронштейна-вложенность, чтобы определить, следует ли разделить или нет:

function splitTokens(var input) { 
    var tokens = []; 
    var currentToken = ""; 
    var nestingLevel = 0; 

    for (var i = 0; i < input.length; i++) { 
     var currentChar = input[i]; 
     if (currentChar === "," && nestingLevel === 0) { 
      tokens.push(currentToken); 
      currentToken=""; 
     } else { 
      currentToken+=currentChar; 
      if (currentChar === "(") { nestingLevel++; } 
      else if (currentChar === ")") { nestingLevel--; } 
     } 
    } 

    if (currentToken.length) { 
     tokens.push(currentToken); 
    } 

    return tokens; 
} 

Обратите внимание, что я не обрабатывать несоответствующие скобки, вы можете добавить логику для этих случаев.

+0

Спасибо @ Арон, он работает как шарм. –

Смежные вопросы