您想在大写字母之前拆分,第一个除外。
仅以大写字母(至少是 ASCII 字母)进行拆分很容易:
// Single character look-ahead for capital letter.
final beforeCapitalLetter = RegExp(r"(?=[A-Z])");
...
var parts = string.split(beforeCapitalLetter);
这里的问题是它也在第一个字母之前分裂,在结果部分中给你一个空的第一个元素。
如果你确定它在那里,你可以删除它。
if (parts.isNotEmpty && parts[0].isEmpty) parts = parts.sublist(1);
或者,您可以使用 RegExp 变得聪明:
// Matches before a capital letter that is not also at beginning of string.
final beforeNonLeadingCapitalLetter = RegExp(r"(?=(?!^)[A-Z])");
List<String> splitPascalCase(String input) =>
input.split(beforeNonLeadingCapitalLetter);
示例结果:
print(splitPascalCase("HelloWorld")); // [Hello, World]
print(splitPascalCase("One")); // [One]
print(splitPascalCase("none")); // [none]
print(splitPascalCase("BFG9000")); // [B, F, G9000]
print(splitPascalCase("XmlHTTPRequest")); // [Xml, H, T, T, P, Request]
(您可能要考虑最后一件事是否是您想要的)。
另一种选择是不拆分,而是匹配你想要的部分。
final pascalWords = RegExp(r"(?:[A-Z]+|^)[a-z]*");
List<String> getPascalWords(String input) =>
pascalWords.allMatches(input).map((m) => m[0]).toList();
这会提取以一个或多个前导大写字母(或字符串开头)开头的所有单词。如果你的字符串只包含字母,它应该和前面的函数一样。如果它包含其他内容,则这些内容将被忽略。
print(getPascalWords("BFG9000")); // [BFG]
print(getPascalWords("XmlHTTPRequest")); // [Xml, HTTPRequest]
更喜欢哪一个取决于您希望获得哪些字符串作为输入,以及您希望如何处理边缘情况:相邻的大写字母?都是大写字母?空字符串?
如果它总是将一个或多个两个字母或更长的单词与第一个字母大写,那么它只是简单的情况,任何一种方法都可以。
编辑:自从首次发布以来,Dart RegExps 已经开始支持后视。这样,也可以通过拆分小写字母和大写字母来使用拆分,正如Serdnad 在评论中所说:
final _pascalWordsRE = RegExp(r"(?<=[a-z])(?=[A-Z])");
List<String> getPascalWords(String input) => pascalWords.split(_pascalWordsRE);
这在一个小写字母之后和一个大写字母之前分割。