Last active
January 14, 2020 06:10
-
-
Save fuxingloh/d2cb8793b586a62545453f589cec5b9b to your computer and use it in GitHub Desktop.
Java regex string splitter that keeps the delimiter. Java string split with delimiter kept.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public class PatternSplit { | |
| private final Pattern pattern; | |
| /** | |
| * @param pattern pattern for the splitter | |
| */ | |
| private PatternSplit(Pattern pattern) { | |
| this.pattern = pattern; | |
| } | |
| /** | |
| * @param input string input | |
| * ` * @return List of result object | |
| */ | |
| public List<String> split(CharSequence input) { | |
| return split(input, 0); | |
| } | |
| /** | |
| * @param input string input | |
| * @param limit limit | |
| * @return List of result object | |
| */ | |
| public List<String> split(CharSequence input, int limit) { | |
| return split(input, limit, s -> s).stream() | |
| .map(o -> (String) o).collect(Collectors.toList()); | |
| } | |
| /** | |
| * @param input string input | |
| * @param limit limit | |
| * @param delimitMapper delimiter function for delimited value | |
| * @return List of result object | |
| */ | |
| public List<Object> split(CharSequence input, int limit, DelimitMapper delimitMapper) { | |
| return split(input, limit, s -> s, delimitMapper); | |
| } | |
| /** | |
| * @param input string input | |
| * @param limit limit | |
| * @param splitMapper splitter function for split value | |
| * @param delimitMapper delimiter function for delimited value | |
| * @return List of result object | |
| */ | |
| public List<Object> split(CharSequence input, int limit, SplitMapper splitMapper, DelimitMapper delimitMapper) { | |
| return split(input, limit, splitMapper, (Matcher matcher) -> | |
| delimitMapper.apply(input.subSequence(matcher.start(), matcher.end()).toString()) | |
| ); | |
| } | |
| /** | |
| * @param input string input | |
| * @param limit limit | |
| * @param splitMapper splitter function for split value | |
| * @param matchMapper delimiter function for delimited value | |
| * @return List of result object | |
| */ | |
| public List<Object> split(CharSequence input, int limit, SplitMapper splitMapper, MatchMapper matchMapper) { | |
| int index = 0; | |
| boolean matchLimited = limit > 0; | |
| List<Object> matchList = new ArrayList<>(); | |
| Matcher m = pattern.matcher(input); | |
| // Add segments before each match found | |
| while (m.find()) { | |
| if (!matchLimited || matchList.size() < limit - 1) { | |
| if (index == 0 && index == m.start() && m.start() == m.end()) { | |
| // no empty leading substring included for zero-width match | |
| // at the beginning of the input char sequence. | |
| continue; | |
| } | |
| Object split = splitMapper.apply(input.subSequence(index, m.start()).toString()); | |
| if (split != null) matchList.add(split); | |
| matchList.add(matchMapper.apply(m)); | |
| index = m.end(); | |
| } else if (matchList.size() == limit - 1) { // last one | |
| Object split = splitMapper.apply(input.subSequence(index, m.start()).toString()); | |
| if (split != null) matchList.add(split); | |
| matchList.add(matchMapper.apply(m)); | |
| index = m.end(); | |
| } | |
| } | |
| // If no match was found, return this | |
| if (index == 0) | |
| return Collections.singletonList(input.toString()); | |
| // Add remaining segment | |
| if (!matchLimited || matchList.size() < limit) | |
| matchList.add(input.subSequence(index, input.length()).toString()); | |
| // Construct result | |
| int resultSize = matchList.size(); | |
| if (limit == 0) | |
| while (resultSize > 0 && matchList.get(resultSize - 1).equals("")) | |
| resultSize--; | |
| return matchList.subList(0, resultSize); | |
| } | |
| /** | |
| * @param pattern regex string | |
| * @param flags pattern flags | |
| * @return PatternSplit | |
| */ | |
| public static PatternSplit compile(String pattern, int flags) { | |
| return new PatternSplit(Pattern.compile(pattern, flags)); | |
| } | |
| /** | |
| * @param pattern regex string | |
| * @return PatternSplit | |
| */ | |
| public static PatternSplit compile(String pattern) { | |
| return new PatternSplit(Pattern.compile(pattern)); | |
| } | |
| @FunctionalInterface | |
| interface SplitMapper extends Function<String, Object> { | |
| } | |
| @FunctionalInterface | |
| interface DelimitMapper extends Function<String, Object> { | |
| } | |
| @FunctionalInterface | |
| interface MatchMapper extends Function<Matcher, Object> { | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public static String[] split(Pattern pattern, CharSequence input, int limit) { | |
| int index = 0; | |
| boolean matchLimited = limit > 0; | |
| ArrayList<String> matchList = new ArrayList<>(); | |
| Matcher m = pattern.matcher(input); | |
| // Add segments before each match found | |
| while (m.find()) { | |
| if (!matchLimited || matchList.size() < limit - 1) { | |
| if (index == 0 && index == m.start() && m.start() == m.end()) { | |
| // no empty leading substring included for zero-width match | |
| // at the beginning of the input char sequence. | |
| continue; | |
| } | |
| String match = input.subSequence(index, m.start()).toString(); | |
| matchList.add(match); | |
| matchList.add(input.subSequence(m.start(), m.end()).toString()); | |
| index = m.end(); | |
| } else if (matchList.size() == limit - 1) { // last one | |
| String match = input.subSequence(index, input.length()).toString(); | |
| matchList.add(match); | |
| matchList.add(input.subSequence(m.start(), m.end()).toString()); | |
| index = m.end(); | |
| } | |
| } | |
| // If no match was found, return this | |
| if (index == 0) | |
| return new String[]{input.toString()}; | |
| // Add remaining segment | |
| if (!matchLimited || matchList.size() < limit) | |
| matchList.add(input.subSequence(index, input.length()).toString()); | |
| // Construct result | |
| int resultSize = matchList.size(); | |
| if (limit == 0) | |
| while (resultSize > 0 && matchList.get(resultSize - 1).equals("")) | |
| resultSize--; | |
| String[] result = new String[resultSize]; | |
| return matchList.subList(0, resultSize).toArray(result); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment