ColoredString implements EnhancedString { @Override public ColoredString replaceText(Pattern p, String rText) { Matcher m = p.matcher(new String(plain)); ColoredString replacement = new ColoredString(rText); char[] lastMatchText = new char[0]; String[] lastMatchCodes = new String[1]; int currentPosition = 0; while (m.find()) { int mStart = m.start(); int mEnd = m.end(); int lastMatchTextLength = lastMatchText.length; int middleLen = mStart - currentPosition; int newLength = lastMatchTextLength + middleLen + replacement.length(); char[] currentText = new char[newLength]; String[] currentCodes = new String[newLength + 1]; System.arraycopy(lastMatchText, 0, currentText, 0, lastMatchTextLength); System.arraycopy(plain, currentPosition, currentText, lastMatchTextLength, middleLen); System.arraycopy(replacement.plain, 0, currentText, lastMatchTextLength + middleLen, replacement.length()); System.arraycopy(lastMatchCodes, 0, currentCodes, 0, lastMatchTextLength + 1); currentCodes[lastMatchTextLength] = mergeCodes(currentCodes[lastMatchTextLength], codes[currentPosition]); System.arraycopy(codes, currentPosition + 1, currentCodes, lastMatchTextLength + 1, middleLen); currentCodes[lastMatchTextLength + middleLen] = mergeCodes(currentCodes[lastMatchTextLength + middleLen], replacement.codes[0]); if (replacement.codes.length > 1) System.arraycopy(replacement.codes, 1, currentCodes, lastMatchTextLength + 1 + middleLen, replacement.length()); currentPosition = mEnd; lastMatchText = currentText; lastMatchCodes = currentCodes; } char[] tempText = new char[lastMatchText.length + plain.length - currentPosition]; String[] tempCodes = new String[lastMatchText.length + plain.length - currentPosition + 1]; System.arraycopy(lastMatchText, 0, tempText, 0, lastMatchText.length); System.arraycopy(lastMatchCodes, 0, tempCodes, 0, lastMatchText.length); System.arraycopy(plain, currentPosition, tempText, lastMatchText.length, plain.length - currentPosition); tempCodes[lastMatchText.length] = mergeCodes(lastMatchCodes[lastMatchText.length], codes[currentPosition]); System.arraycopy(codes, currentPosition + 1, tempCodes, lastMatchText.length + 1, plain.length - currentPosition); return new ColoredString(tempText, tempCodes); } ColoredString(String s); private  ColoredString(char[] plain, String[] codes); int length(); char charAt(int i); CharSequence subSequence(int i, int j); @Override @NotNull String toString(); @Override ColoredString replaceText(Pattern p, String rText); ColoredString patternToLower(Pattern p); ColoredString patternToUpper(Pattern p); @Override boolean equals(Object obj); @Override String getRaw();  }
@Test public void testReplaceText() { String test = "a&3test."; EnhancedString cs = new ColoredString(test); EnhancedString result = cs.replaceText(Pattern.compile("test"), "derp&4"); assertEquals(result.getRaw(), "a&3derp&4."); }