Как разделить строку на ',' или '[|]', если ',' не находится в '{}' - PullRequest
3 голосов
/ 18 марта 2010

Я ищу регулярное выражение, чтобы разбить следующую строку:

aaa[bbb,ccc[ddd,{eee:1,mmm:999}],nnn[0,3]]
aaa[bbb,ccc[ddd,{eee:1, mmm:[123,555]}],nnn[0,3]]
aaa[bbb, ccc[ddd, ddd],nnn[0,3]]
aaa[bbb,ddd[0,3]]

с помощью '[' или ']' или ',' если только ',' не находится в '{}'. Например, разделить 'aaa [bbb, ccc [ddd,' на aaa, bbb, ccc, ddd разрешено, но не {eee: 1, mmm: 999}.

результат:

aaa, bbb, ccc, ddd, {eee:1,mmm:999}, nnn, 0, 3
aaa, bbb, ccc, ddd, {eee:1, mmm:[123,555]}], nnn, 0, 3
aaa, bbb, ccc, ddd, ddd, nnn, 0, 3
aaa, bbb, ddd, 0, 3

Я прочитал много других вопросов, но я не могу изменить регулярное выражение. Есть сообщение, чтобы сделать это, что я хочу.

целевым языком для выражения является javascript.

Ответы [ 5 ]

2 голосов
/ 18 марта 2010

Невозможно сделать это с помощью регулярных выражений и обрабатывать неограниченное количество вложенных скобок; вам нужен стековый парсер.

1 голос
/ 18 марта 2010

Регулярное выражение Perl / PCRE, должно работать и в JS (если {} не вложено):

$_ = 'aaa[bbb,ccc[ddd,{eee:1,mmm:999}],nnn[0,3]]
aaa[bbb,ccc[ddd,{eee:1, mmm:[123,555]}],nnn[0,3]]
aaa[bbb, ccc[ddd, ddd],nnn[0,3]]
aaa[bbb,ddd[0,3]]';

@r = /[^][,{}]+|\{[^}]*}/g;
print join ", ", @r;

Выход:

aaa, bbb, ccc, ddd, {eee:1,mmm:999}, nnn, 0, 3,
aaa, bbb, ccc, ddd, {eee:1, mmm:[123,555]}, nnn, 0, 3,
aaa, bbb,  ccc, ddd,  ddd, nnn, 0, 3,
aaa, bbb, ddd, 0, 3

Грубый перевод на JavaScript:

var input =
    "aaa[bbb,ccc[ddd,{eee:1,mmm:999}],nnn[0,3]]\n" +
    "aaa[bbb,ccc[ddd,{eee:1, mmm:[123,555]}],nnn[0,3]]\n" +
    "aaa[bbb, ccc[ddd, ddd],nnn[0,3]]\n" +
    "aaa[bbb,ddd[0,3]]";

var re = /[^][,{}]+|\{[^}]*}/g;

var result = [];
while (!!(match = re.exec(input)))
{
    result.push(match[0]);
}

// Using <<value>> rather than just a comma, for clarity around
// whether and how "{...}" was processed or not.
write("<<" + result.join(">><<") + ">>");

Непонятно, что означают разрывы строк во входных данных или результатах в вопросе. Выше они представляют собой разрывы строк во входных данных и затем не обрабатываются специально в результате. Если к ним нужно относиться специально, ОП может редактировать соответствующим образом. Итак, это результат вышеприведенного (опять же, используя << и >> в качестве разделителей, а не , для ясности, обрабатывается ли {...}):

<<aaa>><<bbb>><<ccc>><<ddd>><<{eee:1,mmm:999}>><<nnn>><<0>><<3>><<
aaa>><<bbb>><<ccc>><<ddd>><<{eee:1, mmm:[123,555]}>><<nnn>><<0>><<3>><<
aaa>><<bbb>><< ccc>><<ddd>><< ddd>><<nnn>><<0>><<3>><<
aaa>><<bbb>><<ddd>><<0>><<3>>
1 голос
/ 18 марта 2010

Не-регулярным способом было бы просто написать цикл, который проверяет строку символ за символом.Когда он встречает {, увеличивайте переменную.Когда он встречает }, уменьшите значение переменной.Когда он встречает , и переменная, которую вы увеличивали / уменьшали, была равна нулю, добавьте позицию , в список.Когда вы закончите, у вас есть список позиций, где вы хотите разбить строку.

Я предполагаю, что нет никаких закрывающих скобок }, которые появляются перед открывающими скобками {,в противном случае вы можете игнорировать неуместные закрывающие скобки, а не уменьшать значение переменной до отрицательных значений.

0 голосов
/ 18 марта 2010

Предполагая, что вы обрабатываете текст построчно и что фигурные скобки не могут быть вложенными, это разделенное регулярное выражение должно работать:

/ *[\[\],]+ *(?=[^{}]*(?:\{[^{}]*\}[^{}]*)*$)/

Первая часть - *[\[\],]+ * - соответствует одному или нескольким из [, ] или , и любым окружающим пространствам. Остальные - это прогноз, который утверждает, что, если перед сопоставляемыми символами есть какие-либо фигурные скобки, они приходят сбалансированными парами. Если текст правильно сформирован, это гарантирует, что в паре фигурных скобок совпадение не произойдет.

0 голосов
/ 18 марта 2010

Разделите {материал}, в то время как вы разделяете остальные-

function customRx(s){
 s= s.replace(/[\[\],\s]+$/g,'');
 var Rx=/,?(\{[^}]+\}),?/g, Rs=/[\[\],\s]+/, Rc=/^,|,$/g;
 var A= [], i= 0, M, z= 0;
 while((M= Rx.exec(s))!= null){
  i= M.index;
  if(i> z){
   A.push(s.substring(z, i).split(Rs));
  }
  z= Rx.lastIndex;
  A.push(s.substring(i, z).replace(Rc,''));
 }
 if(s.length> z){
  A.push(s.substring(z).split(Rs));
 }
 return A;
}

// тест

var s1= 'aaa[bbb,ccc[ddd,{eee:1,mmm:999}],nnn[0,3]]'+
'aaa[bbb,ccc[ddd,{eee:1, mmm:[123,555]}],nnn[0,3]]'+
'aaa[bbb, ccc[ddd, ddd],nnn[0,3]]'+
'aaa[bbb,ddd[0,3]]';

alert (customRx (s1) .join (','));

возвращаемое значение (добавлены новые строки)>

ааа, bbb, ccc, ddd, {eee: 1, mmm: 999},

nnn, 0,3, aaa, bbb, ccc, ddd, {eee: 1, mmm: [123,555]},

NNN, 0,3, ааа, ГЭБ, ссс, ддд, ддд, NNN,

0,3, ааа, ГЭБ, ддд, 0,3

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...