Alle überlappenden Teilzeichenfolgen, die einer Java-Regex entsprechen

Gibt es eine API-Methode, die alle (möglicherweise überlappenden) Teilzeichenfolgen zurückgibt, die einem regulären Ausdruck entsprechen?

Zum Beispiel habe ich eine Textzeichenfolge:String t = 04/31 412-555-1235;und ich habe ein Muster:Pattern p = new Pattern("\\d\\d+"); das entspricht Zeichenfolgen von zwei oder mehr Zeichen.

Die Übereinstimmungen, die ich bekomme, sind: 04, 31, 412, 555, 1235.

Wie erhalte ich überlappende Übereinstimmungen?

Ich möchte, dass der Code Folgendes zurückgibt: 04, 31, 41, 412, 12, 55, 55, 55, 12, 123, 1235, 23, 235, 35.

Theoretisch sollte es möglich sein - es liegt auf der HandO(n^2) Algorithmus, der alle Teilzeichenfolgen auflistet und mit dem Muster vergleicht.

BEARBEITEN

Anstatt alle Teilzeichenfolgen aufzulisten, ist es sicherer, die zu verwendenregion(int start, int end) Methode inMatcher. Das Prüfen des Musters gegen eine separate, extrahierte Teilzeichenfolge kann das Ergebnis der Übereinstimmung ändern (z. B. wenn am Anfang / Ende des Musters eine nicht erfassende Gruppen- oder Wortgrenzenprüfung erfolgt).

BEARBEITEN 2

Eigentlich ist es unklar, obregion() tut, was Sie für Übereinstimmungen mit der Breite Null erwarten. Die Spezifikation ist vage und Experimente liefern enttäuschende Ergebnisse.

Zum Beispiel:

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

Ich bin mir nicht sicher, was die eleganteste Lösung ist. Ein Ansatz wäre, eine Teilzeichenfolge von zu nehmenline und füllen Sie mit den entsprechenden Begrenzungszeichen aus, bevor Sie prüfen, ob daspat Streichhölzer.

EDIT 3

Hier ist die vollständige Lösung, die ich mir ausgedacht habe. Es kann Muster, Grenzen usw. mit der Breite Null im ursprünglichen regulären Ausdruck verarbeiten. Durchsucht alle Teilzeichenfolgen der Textzeichenfolge und überprüft, ob der reguläre Ausdruck nur an der bestimmten Position übereinstimmt, indem das Muster am Anfang und am Ende mit der entsprechenden Anzahl von Platzhaltern aufgefüllt wird. Es scheint für die Fälle zu funktionieren, die ich ausprobiert habe - obwohl ich keine umfangreichen Tests durchgeführt habe. Es ist sicherlich weniger effizient als es sein könnte.

  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

Hier ist eine bessere Möglichkeit, dies zu tun:https://stackoverflow.com/a/11372670/244526

BEARBEITEN 5

DasJRegex Die Bibliothek unterstützt das Auffinden aller überlappenden Teilzeichenfolgen, die einer Java-Regex entsprechen (obwohl sie anscheinend schon länger nicht mehr aktualisiert wurden). Insbesondere dieDokumentation zur ununterbrochenen Suche spezifiziert:

Mit der unterbrechungsfreien Suche können Sie alle möglichen Vorkommen eines Musters finden, einschließlich solcher, die sich überschneiden oder verschachteln. Dies wird erreicht, indem die Matcher-Methode continue () anstelle von find () verwendet wird.

Antworten auf die Frage(3)

Ihre Antwort auf die Frage