Skip to content

Instantly share code, notes, and snippets.

@loromits
Created May 31, 2018 11:43
Show Gist options
  • Save loromits/ed4f30437106913dcbbae2ccb24c878e to your computer and use it in GitHub Desktop.
Save loromits/ed4f30437106913dcbbae2ccb24c878e to your computer and use it in GitHub Desktop.
struct SubtitleEntry {
let index: Int
let startTime, endTime: TimeInterval
let text: String
}
extension String {
subscript(nsrange: NSRange) -> String? {
return Range(nsrange, in: self)
.flatMap { range in String(self[range]) }
}
}
extension TimeInterval {
init?(timeline: String) {
let components = timeline.components(separatedBy: ":")
guard components.count == 3,
let hours = Double(components[0]),
let minutes = Double(components[1]),
let seconds = Double(components[2].replacingOccurrences(of: ",", with: "."))
else { return nil }
self = hours * 60 * 60 + minutes * 60 + seconds
}
}
enum SrtParser {
private static var pattern: String {
return ["(?<index>^\\d+$)\\n^",
"(?<startTime>\\d\\d:[0-5]\\d:[0-5]\\d,\\d{1,3}) --> ",
"(?<endTime>\\d\\d:[0-5]\\d:[0-5]\\d,\\d{1,3})$\\n",
"(?<text>(?:^.+$\\n?)+)"].joined()
}
private static let expression = try? NSRegularExpression(pattern: pattern, options: .anchorsMatchLines)
static func parse(string: String) -> [SubtitleEntry] {
return expression?
.matches(in: string, range: NSRange(..<string.endIndex, in: string))
.compactMap { result -> SubtitleEntry? in
guard result.numberOfRanges >= 4,
let indexString = string[result.range(withName: "index")],
let index = Int(indexString),
let startString = string[result.range(withName: "startTime")],
let startTime = TimeInterval(timeline: startString),
let endString = string[result.range(withName: "endTime")],
let endTime = TimeInterval(timeline: endString),
let text = string[result.range(withName: "text")]
else { return nil }
return SubtitleEntry(index: index, startTime: startTime, endTime: endTime,
text: text.trimmingCharacters(in: .whitespacesAndNewlines))
} ?? []
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment