CharSequence (@NotNull CharSequence string, @NotNull StringWithId matchingString, @NotNull MatchData matchData) { if (!matchData.matched()) { return string; } Matcher matcher = CAPTURE_GROUP_REGEX.matcher(string); StringBuilder result = new StringBuilder(); int lastPosition = 0; while (matcher.find()) { int groupIndex = StringUtilRt.parseInt(matcher.group(1) != null ? matcher.group(1) : matcher.group(2), -1); if (groupIndex >= 0 && matchData.count() > groupIndex) { result.append(string, lastPosition, matcher.start()); TextMateRange range = matchData.byteOffset(groupIndex); String capturedText = new String(matchingString.bytes, range.start, range.getLength(), StandardCharsets.UTF_8); int numberOfDotsAtTheBeginning = Strings.countChars(capturedText, '.', 0, true); String replacement = capturedText.substring(numberOfDotsAtTheBeginning); String command = matcher.group(3); if ("downcase".equals(command)) { result.append(replacement.toLowerCase(Locale.ROOT)); } else if ("upcase".equals(command)) { result.append(replacement.toUpperCase(Locale.ROOT)); } else { result.append(replacement); } lastPosition = matcher.end(); } } if (lastPosition < string.length()) { result.append(string.subSequence(lastPosition, string.length())); } return result.toString(); }