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

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

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

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 имеют эту функцию.

6 Solutions collect form web for “Регулярное выражение с переменным числом групп?”

Согласно документации , регулярные выражения 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(); } 

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

  • Поддерживает ли MySQL Regexp соответствие Unicode
  • Что означает std :: match_results :: размер возврата?
  • Регулярное выражение для сопоставления URL-адресов в Java
  • Разделить строку на подстроки равной длины в Java
  • Windows: копировать / перемещать файлы с регулярными выражениями имен файлов?
  • В чем сложность регулярного выражения?
  • Прямоугольное соответствие Regex - Java
  • Вложенные круглые скобки
  • regex заменить на callback в c ++ 11?
  • Как удалить файлы в командной строке с регулярными выражениями?
  • C # Regex Split - запятые вне кавычек
  • Interesting Posts

    Текущий SynchronizationContext не может использоваться как TaskScheduler

    Переход на вкладки вправо или влево от текущей вкладки в Notepad ++

    Как исправить MBR без перезаписи HD и без Recovery CD

    Android Geofence в конечном итоге прекратит получать переход

    Как реализовать правильную обработку ошибок HTTP в .NET MVC 2?

    Бутстрап с плагином проверки jQuery

    OSX: назначить расширение для контента

    Насколько неопределенным является неопределенное поведение?

    Android: как интегрировать декодер в мультимедийную инфраструктуру

    Как отправить данные в виде данных формы вместо полезной нагрузки запроса?

    Что отличает MainActivity.this от getApplicationContext ()

    Как прокручивать и просматривать данные на экране GNU

    Как исправить ошибку: «Не удалось найти информацию схемы для атрибута / элемента», создав схему

    В программе Fortran OpenMP отсутствует ускорение CPU_TIME ()

    Удаление STL не работает должным образом?

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