splitAndTrim method
Splits a string into a List of trimmed Strings, potentially avoiding
splitting in the middle of a quoted text.
if respectQuotes
is true - then the string is not split between
quotes. however, this functionality is (currently?) limited:
-
escaping is not supported
-
both ' and " are supported, but even if one is enclosed by the other - it still "counts". for example, the string: "hello ' world" will count as having a beginning ' quote. in the following examples, we use the pattern " ": hello world --> hello world
"hello world" --> "hello world"
"hello world" "nihao shijie" --> "hello world" "nihao shijie"
'hello world' "nihao shijie" --> 'hello world' "nihao shijie"
"hello 'world nihao' shijie" --> "hello 'world nihao' shijie"
"hello 'world" nihao' shijie --> "hello 'world" nihao' shijie
"hello 'world nihao' shijie --> "hello 'world nihao' shijie
"hello'world" nihao'shijie --> "hello'world" nihao'shijie
"hello'world" nihao' shijie --> "hello'world" nihao' shijie
"hello'world" nihao' shijie' --> "hello'world" nihao' shijie'
"hello'world" ni'hao"shi jie" --> "hello'world" ni'hao"shi jie"
Implementation
List<String>? splitAndTrim(String pattern, { bool removeEmpty = true, bool respectQuotes = false }) {
String s = this.trim();
if (s.isEmpty) {
return null;
}
List<String> arrParts = s.split(pattern);
List<String> arrFinal = arrParts;
if (respectQuotes) {
arrFinal = [ ];
int i = 0;
while (i < arrParts.length) {
String part = arrParts[i];
String? ch = part._getQuoteIfOdd();
if (ch != null) {
// there is an unclosed quote. find where it's closed
int nextIdx = -1;
if (i < arrParts.length - 1) {
nextIdx = arrParts.indexWhere((x) => x._hasOddQuotesOf(ch), i + 1);
}
if (nextIdx == -1) {
// no closing quote. so ignore the single quote
}
else {
// concatenate all the remaining parts until the part we found
arrFinal.add(arrParts.sublist(i, nextIdx + 1).join(pattern));
i = nextIdx + 1;
continue;
}
}
// no odd quote; add the part as-is
arrFinal.add(part);
i++;
}
}
List<String> arr = arrFinal.map((x) => x.trim()).toList();
arr.removeWhere((x) => x.isEmpty);
return arr;
}