Swift正则捕获组替换大VTT文件时为何出现挂起?
VTT转SRT函数挂起的原因与解决方案
问题原因
你的代码出现挂起的核心问题在于低效的替换逻辑:
- 每次循环调用
replacing(_:with:)时,会替换字符串中所有匹配当前子串的位置,而非仅当前匹配的那一处。比如如果有多个相同的时间戳前缀,每次循环都会重复替换所有相同的实例,导致大量冗余操作。 - 循环过程中每次替换都会生成新的
String实例,对于包含1500条记录的大文件,内存和时间开销会急剧上升,最终导致函数挂起。
解决方案
使用正则表达式的一次性替换功能,避免循环遍历匹配项,大幅提升效率:
优化后的代码方案1(使用replacingOccurrences)
func VTT2SRT() { var vttTextCopy = vttText // 保留视图中的原vttText // 精准匹配时间戳中的小数点 let timeStampRegex = /(\d\d:\d\d:\d\d)\./ vttTextCopy = vttTextCopy.replacingOccurrences(of: timeStampRegex, with: "$1,") // [其他正常工作的代码] srtText = vttTextCopy // 传递处理结果回视图 }
优化后的代码方案2(使用Swift Regex的replaceAll)
func VTT2SRT() { var vttTextCopy = vttText let timeStampRegex = /(\d\d:\d\d:\d\d)\./ vttTextCopy = timeStampRegex.replaceAll(in: vttTextCopy) { match in "\(match.1)," } // [其他正常工作的代码] srtText = vttTextCopy }
进一步精准匹配(避免误替换其他句号)
如果需要更精准地匹配VTT标准时间戳(格式为HH:MM:SS.mmm),可以修改正则表达式确保仅替换毫秒前的小数点:
let timeStampRegex = /(\d\d:\d\d:\d\d)\.(\d{3})/ vttTextCopy = vttTextCopy.replacingOccurrences(of: timeStampRegex, with: "$1,$2")
方案优势
- 一次性完成所有替换操作,时间复杂度为O(n),效率远高于循环多次替换。
- 无需手动遍历匹配项,避免了重复替换和字符串频繁拷贝的问题,处理大文件时不会出现挂起。
内容的提问来源于stack exchange,提问作者rbkopelman
相关产品推荐
相关产品推荐

