Вы не должны делать это таким образом. Вход в Matcher может быть любой CharSequence, но последовательность не должна изменяться. Совпадение, как у вас, похоже на итерацию по Коллекции при одновременном удалении элементов, это не может работать.
Однако, возможно, есть решение:
while (matcher.find()) {
sb.replace(matcher.start(), matcher.end(), "x");
matcher.region(matcher.start() + "x".length(), sb.length());
}