Регулярное выражение с переменным числом групп?

Можно ли создать регулярное выражение с переменным числом групп?

После запуска этого, например …

Pattern p = Pattern.compile("ab([cd])*ef"); Matcher m = p.matcher("abcddcef"); m.matches(); 

… Я хотел бы иметь что-то вроде

  • m.group(1) = "c"
  • m.group(2) = "d"
  • m.group(3) = "d"
  • m.group(4) = "c" .

(Предыстория: я разбираю некоторые строки данных, и одно из «полей» повторяется. Я хотел бы избежать цикла matcher.find для этих полей.)


Как отметил @Tim Pietzcker в комментариях, perl6 и .NET имеют эту функцию.

Согласно документации , регулярные выражения Java не могут это сделать:

Захваченный вход, связанный с группой, всегда является подпоследовательностью, которую группа недавно сопоставила. Если группа оценивается второй раз из-за количественной оценки, то ее ранее зафиксированное значение, если оно есть, будет сохранено, если вторая оценка не удалась. Согласование строки «aba» с выражением (a (b)?) +, Например, оставляет группу 2, установленную в «b». Весь захваченный вход отбрасывается в начале каждого матча.

(выделено мной)

 Pattern p = Pattern.compile("ab(?:(c)|(d))*ef"); Matcher m = p.matcher("abcdef"); m.matches(); 

должен делать то, что вы хотите.

РЕДАКТИРОВАТЬ:

@aioobe, я понимаю сейчас. Вы хотите сделать что-то вроде грамматики

 A ::==    Foo ::== "foo" Baz ::== "baz" Bars ::==   | ε Bar ::== "A" | "B" 

и вытащить все индивидуальные матчи Bar .

Нет, нет способа сделать это с помощью java.util.regex . Вы можете повторять и использовать регулярное выражение в матче с Bars или использовать генератор синтаксического анализатора, например ANTLR, и прикреплять побочный эффект к Bar .

Вы можете использовать split, чтобы получить нужные вам поля в массив и выполнить цикл.

http://download.oracle.com/javase/1,5.0/docs/api/java/lang/String.html#split(java.lang.String )

Я не использовал java regex, но для многих языков ответ: Нет.

Группы захвата, кажется, создаются, когда регулярное выражение анализируется и заполняется, когда оно соответствует строке. Выражение (a)|(b)(c) имеет три группы захвата, только если один или два из них могут быть заполнены. (a)* имеет только одну группу, парсер покидает последний матч в группе после сопоставления.

Я бы подумал, что откат тормозит это поведение и говорит о влиянии /([\S\s])/ в его накопительном состоянии группировки на нечто вроде Библии. Даже если это можно сделать, вывод непознаваем, поскольку группы потеряют позиционное значение. Лучше сделать отдельное регулярное выражение на подобном виде в глобальном смысле и внести его в массив.

У меня была очень похожая проблема, и мне удалось сделать «переменное количество групп», но комбинация цикла while и сброса совпадения.

  int i=0; String m1=null, m2=null; while(matcher.find(i) && (m1=matcher.group(1))!=null && (m2=matcher.group(2))!=null) { // do work on two found groups i=matcher.end(); } 

Но это для моей проблемы (с двумя повторяющимися

  Pattern pattern = Pattern.compile("(?<=^ab[cd]{0,100})[cd](?=[cd]{0,100}ef$)"); Matcher matcher = pattern.matcher("abcddcef") int i=0; String res=null; while(matcher.find(i) && (res=matcher.group())!=null) { System.out.println(res); i=matcher.end(); } 

Вы теряете возможность указывать произвольную длину повторения с помощью * или + потому что внешний вид и внешний вид должны быть предсказуемой длины.

  • Разделить строку, на каждой n-й позиции
  • Как удалить файлы в командной строке с регулярными выражениями?
  • В чем сложность регулярного выражения?
  • Электронная почта Java regex
  • Какое регулярное выражение будет соответствовать действующим международным телефонным номерам?
  • Лучшее HashTag Regex
  • Regex: удалить строки, содержащие
  • Как сделать регулярное выражение для нескольких строк в Notepad ++?
  • Вложенные круглые скобки
  • Как использовать условные обозначения при замене в Notepad ++ с помощью регулярных выражений
  • Проверка номеров кредитных карт Regex
  • Interesting Posts

    Будет ли мой ноутбук в порядке с этим другим зарядным устройством для ноутбука?

    Удаленный рабочий стол на сервер через промежуточный компьютер

    «dragleave» родительского элемента срабатывает при перетаскивании дочерних элементов

    Как загрузить изображение из активов?

    getExtra от Intent, запущенного из ожидающего

    Правильное распределение многомерных массивов

    Есть ли разница между «ListView.invalidateViews ()» и «Adapter.notifyDataSetChanged ()»?

    Место на жестком диске меньше рекламируемого

    bootstrap-typeahead.js добавляет слушателя на событие select

    Как получить индексы N максимальных значений в массиве NumPy?

    Создание файла .reg для Windows 7

    Какой инструмент может генерировать MD5 из командной строки?

    Рабочая станция VMware изолирует гостевой доступ к отдельному интернету

    Почему плохой практикой является вызов System.gc ()?

    Отображение Pdf в браузере с помощью Java-сервлета

    Давайте будем гением компьютера.