Source:
public Slice regexpReplace(@SqlType("varchar") Slice source, @SqlType(JoniRegexpType.NAME) Regex pattern, @SqlType("function(array(varchar), varchar(x))") UnaryFunctionInterface replaceFunction) { if (pageBuilder.isFull()) { pageBuilder.reset(); } BlockBuilder matchedRegionBlockBuilder = pageBuilder.getBlockBuilder(0); Matcher matcher = pattern.matcher(source.getBytes()); SliceOutput sliceOutput = new DynamicSliceOutput(source.length()); int lastEnd = 0; int nextStart = 0; while (true) { int offset = matcher.search(nextStart, source.length(), Option.DEFAULT); if (offset == -1) { break; } if (matcher.getEnd() == matcher.getBegin()) { nextStart = matcher.getEnd() + 1; } else { nextStart = matcher.getEnd(); } Slice sliceBetweenReplacements = source.slice(lastEnd, matcher.getBegin() - lastEnd); lastEnd = matcher.getEnd(); sliceOutput.appendBytes(sliceBetweenReplacements); Region matchedRegion = matcher.getEagerRegion(); int numGroupsToLambda = matchedRegion.numRegs - 1; for (int i = 1; i <= numGroupsToLambda; i++) { if (matchedRegion.beg[i] >= 0 && matchedRegion.end[i] >= 0) { VARCHAR.writeSlice(matchedRegionBlockBuilder, source, matchedRegion.beg[i], matchedRegion.end[i] - matchedRegion.beg[i]); } else { matchedRegionBlockBuilder.appendNull(); } } pageBuilder.declarePositions(numGroupsToLambda); Block toBeReplaced = matchedRegionBlockBuilder.getRegion(matchedRegionBlockBuilder.getPositionCount() - numGroupsToLambda, numGroupsToLambda); Slice replacedSlice = (Slice) replaceFunction.apply(toBeReplaced); if (replacedSlice != null) { sliceOutput.appendBytes(replacedSlice); } else { return null; } } sliceOutput.appendBytes(source.getBytes(), lastEnd, source.length() - lastEnd); return sliceOutput.slice(); }

Target:
public Slice regexpReplace( @SqlType("varchar") Slice source, @SqlType(JoniRegexpType.NAME) Regex pattern, @SqlType("function(array(varchar), varchar(x))") UnaryFunctionInterface replaceFunction) { Matcher matcher = pattern.matcher(source.getBytes()); if (matcher.search(0, source.length(), Option.DEFAULT) == -1) { return source; } SliceOutput output = new DynamicSliceOutput(source.length()); if (pageBuilder.isFull()) { pageBuilder.reset(); } BlockBuilder blockBuilder = pageBuilder.getBlockBuilder(0); int groupCount = pattern.numberOfCaptures(); int appendPosition = 0; int nextStart = 0; do { if (matcher.getEnd() == matcher.getBegin()) { nextStart = matcher.getEnd() + 1; } else { nextStart = matcher.getEnd(); } Slice unmatched = source.slice(appendPosition, matcher.getBegin() - appendPosition); appendPosition = matcher.getEnd(); output.appendBytes(unmatched); Region matchedRegion = matcher.getEagerRegion(); for (int i = 1; i <= groupCount; i++) { if (matchedRegion.beg[i] >= 0 && matchedRegion.end[i] >= 0) { VARCHAR.writeSlice(blockBuilder, source, matchedRegion.beg[i], matchedRegion.end[i] - matchedRegion.beg[i]); } else { blockBuilder.appendNull(); } } pageBuilder.declarePositions(groupCount); Block target = blockBuilder.getRegion(blockBuilder.getPositionCount() - groupCount, groupCount); Slice replaced = (Slice) replaceFunction.apply(target); if (replaced == null) { return null; } output.appendBytes(replaced); } while (matcher.search(nextStart, source.length(), Option.DEFAULT) != -1); output.writeBytes(source, appendPosition, source.length() - appendPosition); return output.slice(); }