Я пытаюсь решить wordEnds from codingbat.com с помощью regex.
Учитывая строку и непустую строку слова, верните строку, состоящую из каждого char, непосредственно перед и сразу после каждого появления слова в строке. Игнорировать случаи, когда char нет или после слова, а char может быть дважды включен, если он находится между двумя словами.
wordEnds("abcXY123XYijk", "XY") → "c13i" wordEnds("XY123XY", "XY") → "13" wordEnds("XY1XY", "XY") → "11" wordEnds("XYXY", "XY") → "XY"
Это самое простое, поскольку я могу сделать это с моим текущим знанием регулярного выражения:
public String wordEnds(String str, String word) {
  return str.replaceAll(
     ".*?(?=word)(?<=(.|^))word(?=(.|$))|.+"
       .replace("word", java.util.regex.Pattern.quote(word)),
     "$1$2"
  );
}
 replace используется для размещения в фактической строке word в шаблоне для удобочитаемости. Pattern.quote не обязательно передавать свои тесты, но я думаю, что это необходимо для правильного решения на основе регулярных выражений.
Регулярное выражение имеет две основные части:
-  Если после сопоставления как можно большего количества символов ".*?",wordвсе еще можно найти "(?=word)", затем найдите, чтобы захватить любой символ, предшествующий ему "(?<=(.|^))", совпадение "word", и посмотрите, чтобы захватить любой символ после него "(?=(.|$))".-  Исходный тест "if" гарантирует, что атомный lookbehind захватывает, только если есть word
- Использование lookahead для захвата следующего символа не потребляет его, поэтому его можно использовать как часть дальнейшего сопоставления
 
-  Исходный тест "if" гарантирует, что атомный lookbehind захватывает, только если есть 
-  В противном случае сопоставьте то, что осталось "|.+"- Группы 1 и 2 будут записывать пустые строки
 
Я думаю, что это работает во всех случаях, но это, очевидно, довольно сложно. Мне просто интересно, могут ли другие предложить более простое регулярное выражение для этого.
Примечание. Я не ищу решение с помощью indexOf и цикла. Я хочу решение replaceAll на основе регулярного выражения. Я также нуждаюсь в рабочем регулярном выражении, которое передает все тесты кодирования.
Мне удалось уменьшить появление word внутри шаблона только до одного.
".+?(?<=(^|.)word)(?=(.?))|.+"
Я все еще смотрю, можно ли это упростить, но у меня также есть другой вопрос:
-  С помощью этого последнего шаблона я упростил .|$только.?, но если я попытался упростить^|.до.?, это не сработает. Почему это?
