Dart正则表达式如何获取所有匹配分组的起止索引位置
Dart正则表达式获取所有分组起止索引的解决方案
问题根因
你之前代码返回所有分组起止索引一致,是因为调用了无参的match.start/match.end,这两个属性返回的是整个正则表达式匹配结果的全局起止位置,而非单个捕获分组的位置。
实现方法
Dart的RegExpMatch类原生提供了带参数的start(int group)和end(int group)方法,传入分组的索引值即可直接获取对应分组的起止偏移量,无需读取私有属性。
单匹配场景修正代码
void main() { const String EMAIL = r'email\s+id\s*:\s*(.+?)(?:\s|$)'; const String sampleString = " Email Id: example@domain.com This is a very long useless string that follows the email "; print(firstMatches(sampleString, EMAIL)); } // 返回结构改为 分组内容: [起始索引, 结束索引] Map<String, List<int>> firstMatches( String txt, String pattern, ) { Map<String, List<int>> groups = {}; RegExp regExp = RegExp(pattern, caseSensitive: false, multiLine: false); RegExpMatch? match = regExp.firstMatch(txt); if (match != null) { for (int i = 0; i < match.groupCount + 1; i++) { final groupContent = match.group(i)?.trim() ?? ""; // 传入分组索引获取对应起止位置 final groupStart = match.start(i); final groupEnd = match.end(i); groups[groupContent] = [groupStart, groupEnd]; } } return groups; }
运行上述代码可得到符合预期的输出:
- 分组0(整个匹配结果):起始索引5,结束索引35
- 分组1(邮箱内容):起始索引16,结束索引34
多匹配场景(每行多结果)实现代码
如果需要获取一行文本中所有匹配结果的所有分组索引,可使用regExp.allMatches遍历所有匹配项:
List<Map<String, List<int>>> allMatchesWithGroupIndices(String txt, String pattern) { List<Map<String, List<int>>> allResults = []; RegExp regExp = RegExp(pattern, caseSensitive: false); final matches = regExp.allMatches(txt); for (final match in matches) { Map<String, List<int>> currentMatchGroups = {}; for (int i = 0; i < match.groupCount + 1; i++) { final groupContent = match.group(i)?.trim() ?? ""; currentMatchGroups[groupContent] = [match.start(i), match.end(i)]; } allResults.add(currentMatchGroups); } return allResults; }
内容的提问来源于stack exchange,提问作者bluenile
相关产品推荐
相关产品推荐

