Все перекрывающиеся подстроки, соответствующие регулярному выражению Java

Есть ли метод API, который возвращает все (возможно, перекрывающиеся) подстроки, которые соответствуют регулярному выражению?

Например, у меня есть текстовая строка:String t = 04/31 412-555-1235;и у меня есть шаблон:Pattern p = new Pattern("\\d\\d+"); это соответствует строкам из двух или более символов.

Матчи, которые я получаю: 04, 31, 412, 555, 1235.

Как получить совпадающие спички?

Я хочу вернуть код: 04, 31, 41, 412, 12, 55, 555, 55, 12, 123, 1235, 23, 235, 35.

Теоретически это должно быть возможно - есть очевидноеO(n^2) алгоритм, который перечисляет и проверяет все подстроки по шаблону.

EDIT

Вместо перечисления всех подстрок безопаснее использоватьregion(int start, int end) метод вMatcher, Проверка шаблона по отдельной, извлеченной подстроке может изменить результат совпадения (например, если в начале / конце шаблона есть не захватывающая группа или проверка границы слова).

EDIT 2

На самом деле неясно, является лиregion() делает то, что вы ожидаете для совпадений с нулевой шириной. Спецификация нечеткая, и эксперименты дают неутешительные результаты.

Например:

String line = "xx90xx";
String pat = "\\b90\\b";
System.out.println(Pattern.compile(pat).matcher(line).find()); // prints false
for (int i = 0; i < line.length(); ++i) {
  for (int j = i + 1; j <= line.length(); ++j) {
    Matcher m = Pattern.compile(pat).matcher(line).region(i, j);
    if (m.find() && m.group().size == (j - i)) {
      System.out.println(m.group() + " (" + i + ", " + j + ")"); // prints 90 (2, 4)
    }
  }
}

Я не уверен, какое самое элегантное решение. Один из подходов состоит в том, чтобы взять подстрокуline и добавьте соответствующие граничные символы, прежде чем проверять,pat Матчи.

EDIT 3

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

  public static void allMatches(String text, String regex)
  {
    for (int i = 0; i < text.length(); ++i) {
      for (int j = i + 1; j <= text.length(); ++j) {
        String positionSpecificPattern = "((?<=^.{"+i+"})("+regex+")(?=.{"+(text.length() - j)+"}$))";
        Matcher m = Pattern.compile(positionSpecificPattern).matcher(text);

        if (m.find()) 
        {   
          System.out.println("Match found: \"" + (m.group()) + "\" at position [" + i + ", " + j + ")");
        }   
      }   
    }   
  }

EDIT 4

Вот лучший способ сделать это:https://stackoverflow.com/a/11372670/244526

EDIT 5

JRegex библиотека поддерживает поиск всех перекрывающихся подстрок, соответствующих регулярному выражению Java (хотя, как представляется, в последнее время оно не обновлялось). В частности,документация по непрерывному поиску определяет:

Using non-breaking search you can finding all possible occureneces of a pattern, including those that are intersecting or nested. This is achieved by using the Matcher's method proceed() instead of find()

Ответы на вопрос(3)

Ваш ответ на вопрос