Регулярное выражение для разделения на запятые, не заключенные в круглые скобки - PullRequest
4 голосов
/ 10 марта 2009

Мне не удалось написать регулярное выражение, чтобы использовать его в выражении String.split (Java), например, для разбиения на запятые, которые не указаны в скобках.

Пример:

(54654,4565) :( 45651,65423), 4565: 45651, (4565,4564): 45651

Должно дать 3 строки:

  1. (54654,4565) :( 45651,65423)
  2. 4565: 45651
  3. (4565,4564): 45651

Любая помощь высоко ценится.

Ответы [ 3 ]

6 голосов
/ 10 марта 2009

Вы можете сделать это с помощью простого взгляда, с которым легче работать, чем с взглядом назад.

String[] parts = str.split(",(?![^()]*+\\))");

Но другие респонденты правы: если вы не смогли придумать это регулярное выражение самостоятельно, что вы будете делать, когда изменятся требования? Вы, вероятно, лучше с длинным решением, которое вы действительно понимаете.

0 голосов
/ 10 марта 2009

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

(а,) б, (с, (д,) е)

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

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

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

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

0 голосов
/ 10 марта 2009

Это работает:

String regex = "((?<!\\d),)|(,(?!\\d))";

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

В результате, если вы посмотрите на этот текст:

"45651:65423,4565:45651"

тогда это решение не сработает (как пример). Если вы более точно определите, какие данные вы ожидаете, мы сможем адаптировать наши ответы к вашей ситуации.

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