splitKeepingDelimiter method

  1. @useResult
List<String> splitKeepingDelimiter(
  1. Pattern pattern, {
  2. bool includeDelimiters = false,
})

Splits by pattern and returns list of segments; optionally includes matches as separate elements.

If includeDelimiters is true, the pattern matches are included after each segment (except the last). pattern is a RegExp or String; if String, it is interpreted as a literal.

Throws ArgumentError if pattern is an empty String.

Example:

'a-b-c'.splitKeepingDelimiter('-', includeDelimiters: true);  // ['a', '-', 'b', '-', 'c']

Implementation

@useResult
List<String> splitKeepingDelimiter(Pattern pattern, {bool includeDelimiters = false}) {
  if (isEmpty) return <String>[];
  if (pattern is String && pattern.isEmpty) {
    throw ArgumentError(_kErrPatternNotEmpty, _kParamPattern);
  }
  final List<Match> matches = pattern.allMatches(this).toList();
  final int matchCount = matches.length;
  // N matches produce one more segment than there are matches, and keeping
  // delimiters adds a further element for each match. Sizing the buffer
  // exactly to that total avoids any reallocation while filling it.
  final int capacity = 1 + matchCount + (includeDelimiters ? matchCount : 0);
  final List<String> result = List<String>.filled(capacity, '');
  int start = 0;
  int idx = 0;
  for (final Match m in matches) {
    result[idx++] = substring(start, m.start);
    if (includeDelimiters) {
      final delim = m.group(0);
      if (delim != null) result[idx++] = delim;
    }
    start = m.end;
  }
  result[idx] = substring(start);
  return result.sublist(0, idx + 1);
}