如何简洁实用编写遵循DRY原则的Dart StringBuffer写入代码
优化Dart歌词解析代码的几种DRY方案
针对这段解析歌词时间的Dart代码,有几种实用简洁的优化方式,能更好地遵循DRY(Don't Repeat Yourself)原则:
方案一:正则表达式匹配+循环输出
用正则直接捕获时间各部分和歌词内容,再通过循环批量写入结果,彻底消除手动索引和重复的write操作:
void main() { final lyric = '[00:12.34]Row, row, row your boat'; // 匹配[MM:SS.hh]格式,捕获分钟、秒、毫秒、歌词四个分组 final timeRegex = RegExp(r'\[(\d{2}):(\d{2})\.(\d{2})\](.*)'); final match = timeRegex.firstMatch(lyric)!; final buffer = StringBuffer(); // 用列表关联标签和捕获组索引,循环生成内容 const contentParts = [ ('minutes:', 1), ('seconds:', 2), ('hundredths:', 3), ('lyrics:', 4), ]; for (final (label, groupIdx) in contentParts) { buffer.write('$label ${match.group(groupIdx)}\n'); } print(buffer.toString().trimRight()); }
方案二:提取索引逻辑+循环处理
如果不想用正则,可把各部分的标签、起止索引整理成列表,通过循环完成写入,消除重复的代码块:
void main() { final lyric = '[00:12.34]Row, row, row your boat'; final openBracketIndex = lyric.indexOf('['); final colonIndex = lyric.indexOf(':'); final dotIndex = lyric.indexOf('.'); final endBracketIndex = lyric.indexOf(']'); final buffer = StringBuffer(); // 定义各部分的标签和截取范围 final contentParts = [ ('minutes:', openBracketIndex + 1, colonIndex), ('seconds:', colonIndex + 1, dotIndex), ('hundredths:', dotIndex + 1, endBracketIndex), ('lyrics:', endBracketIndex + 1, null), // null表示截取到字符串末尾 ]; for (final (label, start, end) in contentParts) { buffer.write('$label ${lyric.substring(start, end)}\n'); } print(buffer.toString().trimRight()); }
方案三:多行字符串直接拼接(极简版)
如果输出格式固定,用多行字符串直接拼接结果,代码最简洁:
void main() { final lyric = '[00:12.34]Row, row, row your boat'; final match = RegExp(r'\[(\d{2}):(\d{2})\.(\d{2})\](.*)').firstMatch(lyric)!; final output = ''' minutes: ${match.group(1)} seconds: ${match.group(2)} hundredths: ${match.group(3)} lyrics: ${match.group(4)} '''; print(output.trim()); }
这些方案的核心都是消除重复的代码块:正则方案适配性最强,循环索引方案保留原逻辑的同时简化代码,多行字符串方案适合输出格式固定的场景。
内容的提问来源于stack exchange,提问作者zex_rectooor
相关产品推荐
相关产品推荐

