Wszystkie nakładające się podciągi pasujące do wyrażenia regularnego java

Czy istnieje metoda API, która zwraca wszystkie (prawdopodobnie nakładające się) podciągi, które pasują do wyrażenia regularnego?

Na przykład mam ciąg tekstowy:String t = 04/31 412-555-1235;i mam wzór:Pattern p = new Pattern("\\d\\d+"); pasujący do ciągów dwóch lub więcej znaków.

Mecze, które dostaję, to: 04, 31, 412, 555, 1235.

Jak uzyskać nakładające się mecze?

Chcę, aby kod powrócił: 04, 31, 41, 412, 12, 55, 555, 55, 12, 123, 1235, 23, 235, 35.

Teoretycznie powinno być to możliwe - jest oczywisteO(n^2) algorytm wyliczający i sprawdzający wszystkie podciągi względem wzorca.

EDYTOWAĆ

Zamiast wyliczać wszystkie podciągi, bezpieczniej jest użyćregion(int start, int end) metoda wMatcher. Sprawdzanie wzorca w oddzielnym, wyodrębnionym podciągu może zmienić wynik dopasowania (np. Jeśli na początku / końcu wzorca znajduje się grupa nie przechwytująca lub sprawdzanie granicy wyrazu).

EDYCJA 2

Właściwie nie jest jasne, czyregion() robi to, czego oczekujesz dla dopasowań o zerowej szerokości. Specyfikacja jest niejasna, a eksperymenty przynoszą rozczarowujące wyniki.

Na przykład:

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)
    }
  }
}

Nie jestem pewien, jakie jest najbardziej eleganckie rozwiązanie. Jednym z podejść byłoby pobranie podciągówline i zaznacz odpowiednimi znakami granicznymi przed sprawdzeniem, czypat mecze.

EDYCJA 3

Oto pełne rozwiązanie, które wymyśliłem. Może obsługiwać wzory, granice itp. O zerowej szerokości w oryginalnym wyrażeniu regularnym. Przegląda wszystkie podciągi ciągu tekstowego i sprawdza, czy wyrażenie regularne pasuje tylko do określonej pozycji, wypełniając wzorzec odpowiednią liczbą symboli wieloznacznych na początku i na końcu. Wydaje się, że działa w przypadkach, które wypróbowałem - chociaż nie przeprowadziłem dokładnych testów. Z pewnością jest mniej wydajny niż mógłby być.

  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 + ")");
        }   
      }   
    }   
  }

EDYCJA 4

Oto lepszy sposób:https://stackoverflow.com/a/11372670/244526

EDYTUJ 5

TheJRegex biblioteka obsługuje wyszukiwanie wszystkich nakładających się podciągów pasujących do wyrażenia regularnego java (chociaż wydaje się, że nie zostało zaktualizowane za jakiś czas). W szczególnościdokumentacja dotycząca wyszukiwania bez łamania określa:

Używając wyszukiwania bez łamania, możesz znaleźć wszystkie możliwe występy wzorca, w tym przecinające się lub zagnieżdżone. Osiąga się to za pomocą metody Matchera continue () zamiast find ()

questionAnswers(3)

yourAnswerToTheQuestion