codingbat wordEnds using regex

Ich versuche zu lösenwordEnds von codingbat.com Verwenden von Regex.

Geben Sie eine Zeichenfolge und eine nicht leere Wortfolge ein und geben Sie eine Zeichenfolge zurück, die aus jedem Zeichen unmittelbar vor und unmittelbar nach jedem Auftreten des Worts in der Zeichenfolge besteht. Ignorieren Sie Fälle, in denen vor oder nach dem Wort kein Zeichen steht, und ein Zeichen kann zweimal enthalten sein, wenn es zwischen zwei Wörtern liegt.

wordEnds("abcXY123XYijk", "XY") → "c13i"
wordEnds("XY123XY", "XY") → "13"
wordEnds("XY1XY", "XY") → "11"
wordEnds("XYXY", "XY") → "XY"

Dies ist das einfachste, wie ich es mit meinen aktuellen Kenntnissen von Regex machen kann:

public String wordEnds(String str, String word) {
  return str.replaceAll(
     ".*?(?=word)(?<=(.|^))word(?=(.|$))|.+"
       .replace("word", java.util.regex.Pattern.quote(word)),
     "$1$2"
  );
}

replace wird verwendet, um in das aktuelle @ einzufügword string in das Muster für die Lesbarkeit.Pattern.quote ist nicht erforderlich, um ihre Tests zu bestehen, aber ich denke, es ist für eine ordnungsgemäße Regex-basierte Lösung erforderlich.

Die Regex hat zwei Hauptteile:

Wenn nach dem Abgleichen so wenig Zeichen wie möglich ".*? ",word kann noch gefunden werden "(?=word) ", dann schau nach, um jedes Zeichen unmittelbar davor zu erfassen"(?<=(.|^))", Spiel "word "und freue mich darauf, jedes darauf folgende Zeichen zu erfassen"(?=(.|$)) ".Der anfängliche "if" -Test stellt sicher, dass der atomare Lookbehind nur erfasst, wenn ein @ vorhanden iswordMit dem Lookahead zum Erfassen des folgenden Zeichens wird es nicht verbraucht, sodass es als Teil des weiteren Abgleichs verwendet werden kann Anderenfalls übereinstimmen, was übrig ist "|.+"Groups 1 und 2 würden leere Zeichenfolgen erfassen

Ich denke, das funktioniert in allen Fällen, aber es ist offensichtlich ziemlich komplex. Ich frage mich nur, ob andere einen einfacheren regulären Ausdruck vorschlagen können, um dies zu tun.

Hinweis: Ich suche keine Lösung mitindexOf und eine Schleife. Ich möchte ein auf Regex basierendesreplaceAll Lösung. Ich brauche auch eine funktionierende Regex, die alle Codingbat-Tests besteht.

Ich habe es geschafft, das Auftreten von @ zu reduzierword innerhalb des Musters auf nur einen.

".+?(?<=(^|.)word)(?=(.?))|.+"

Ich suche immer noch, ob es möglich ist, dies weiter zu vereinfachen, aber ich habe auch eine andere Frage:

it diesem neuesten Muster habe ich @ vereinfac.|$ bis nur.? erfolgreich, aber wenn ich ähnlich versucht habe, @ zu vereinfach^|. zu.? es funktioniert nicht. Warum das

Antworten auf die Frage(3)

Ihre Antwort auf die Frage