Разделение строк регулярным выражением на символе, не содержащееся в () - PullRequest
0 голосов
/ 19 февраля 2009

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

Пример строки:

`table1`.`lname`,`table1`.`fname`,if(foo is not null,foo,if(bar is not null,bar,table3.baz)),`table3`.`shu`

Я хочу разбить его на массив, похожий на

(
  0=>`table1`.`lname`
  1=>`table1`.`fname`
  2=>if(foo is not null,foo,if(bar is not null,bar,table3.baz))
  3=>`table3`.`shu`
)

Есть идеи, как решить эту проблему?

- Dave

Ответы [ 4 ]

4 голосов
/ 19 февраля 2009

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

Я думаю, что здесь уже были подобные вопросы, но мне было трудно их найти. Этот ответ однако должен помочь объяснить.

0 голосов
/ 19 февраля 2009

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

/(([^,]*\(.*\))|[^,]*)/g

Просто помните, что это не удастся, если у вас есть ) где-то разное или если у вас есть несколько наборов скобок, которые необходимо проанализировать.

0 голосов
/ 19 февраля 2009

Regex не очень хорош в этом. Рассмотрим следующий фрагмент:

(а) б (с (д) е)

Где каждая буква представляет запятую (цель поиска). Исходя из вашего вопроса, вы бы хотели совпадать только с запятой b. Хитрость в том, что выражения, как правило, либо жадные, либо не жадные, без среднего уровня.

Жадное выражение будет видеть ( в самом начале сегмента и ) в самом конце и принимать все внутри них, независимо от того, где в другом месте есть закрывающие скобки. Ничего не будет совпадать.

Нечестивое выражение будет принимать только наименьший возможный набор, начиная с начала. Он будет соответствовать запятой b, но также будет рассматривать этот сегмент как единое целое: (c(d), а затем перейдет также к запятой e.

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

0 голосов
/ 19 февраля 2009

Я бы посмотрел на вашем любимом языке, чтобы увидеть, есть ли специальный модуль для обработки файлов CSV. У Ruby есть CSV (в последних версиях он заменен FasterCSV ), который отлично справился бы с вашей проблемой.

Это сложнее, чем одно регулярное выражение, но выполнит работу.

Perl имеет этот модуль Parse :: CSV .

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