Referenz: https://stackoverflow.com/questions/17971466/java-regex-overlapping-matches
Normalerweise wird beim Abgleichen eines regulären Ausdrucks der in einer Übereinstimmung verwendete Zeichenfolgenteil in einer anderen Übereinstimmung nicht zweimal verwendet.
Zum Beispiel aus der Zeichenfolge " _apple_banana_cherry_
"
Wenn Sie mit / _ [^ _] + _ /
übereinstimmen, können Sie zwei Dinge erhalten, _apple_
und _cherry_
.
Wenn Sie das überlappende "\ _" verwenden möchten, um drei, "apple", "banana" und "cherry" zu nehmen, müssen Sie eine spezielle angeben.
Eine einfache Möglichkeit besteht darin, das reguläre Ausdruckspaket "regex" zu verwenden und mit der Option "overlapped = True" abzugleichen.
{.python}
>>> import regex as re
>>> re.findall("_[^_]+_", "_apple_banana_cherry_")
['_apple_', '_cherry_']
>>> re.findall("_[^_]+_", "_apple_banana_cherry_", overlapped=True)
['_apple_', '_banana_', '_cherry_']
Im Fall von Java ist es einfach, das Standardpaket für reguläre Ausdrücke zu verwenden und den startIndex zu verschieben.
{.java}
Matcher m = Pattern.compile("_[^_]+(_)").matcher("_apple_banana_cherry_");
if (m.find()) {
do {
System.out.println(m.group());
} while (m.find(m.start(1)));
}
Kommentar:
Mit / _ [^ _] + (_) /
wird das zweite erscheinende _
in ()
eingeschlossen, damit es als Gruppe 1 erfasst werden kann.
m.start (1)
gibt den ersten Index der Gruppe 1 zurück.
m.find (N)
bedeutet, dass die Übereinstimmung mit dem N-ten Zeichen beginnt.
"M.Find (m.start (1))" bedeutet also, m.find () vom ersten Index der Gruppe 1 aus zu starten.
Mit anderen Worten, in der zweiten und den folgenden Schleifen wird die nächste Übereinstimmung von "_" am Ende der übereinstimmenden Zeichenfolge gestartet.
note: Es kann einfacher sein, eine benannte Gruppe zu verwenden, um anzugeben, welche Gruppe der erste Index für die nächste Übereinstimmung sein soll.
{.example}
(?<name>PATTERN)
Möglicherweise benötigen Sie auch eine Nicht-Erfassungsgruppe für komplexere Übereinstimmungsmuster.
{.example}
(?:PATTERN)