mirror of
				https://github.com/yattee/yattee.git
				synced 2025-11-04 06:32:03 +00:00 
			
		
		
		
	Merge pull request #597 from stonerl/regex-for-chapters
more robust regex for chapters from description
This commit is contained in:
		@@ -144,52 +144,63 @@ extension VideosAPI {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    func extractChapters(from description: String) -> [Chapter] {
 | 
					    func extractChapters(from description: String) -> [Chapter] {
 | 
				
			||||||
        guard let chaptersRegularExpression = try? NSRegularExpression(
 | 
					        /*
 | 
				
			||||||
            pattern: "(?<start>(?:[0-9]+:){1,}(?:[0-9]+))(?:\\s)+(?:- ?)?(?<title>.*)",
 | 
					         The following chapter patterns are covered:
 | 
				
			||||||
            options: .caseInsensitive
 | 
					 | 
				
			||||||
        ) else { return [] }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let chapterLines = chaptersRegularExpression.matches(
 | 
					         start - end - title / start - end: Title / start - end title
 | 
				
			||||||
            in: description,
 | 
					         start - title / start: title / start title / [start] - title / [start]: title / [start] title
 | 
				
			||||||
            range: NSRange(description.startIndex..., in: description)
 | 
					         index. title - start / index. title start
 | 
				
			||||||
        )
 | 
					         title: (start)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return chapterLines.compactMap { line in
 | 
					         The order is important!
 | 
				
			||||||
            let titleRange = line.range(withName: "title")
 | 
					         */
 | 
				
			||||||
            let startRange = line.range(withName: "start")
 | 
					        let patterns = [
 | 
				
			||||||
 | 
					            "(?<=\\n|^)\\s*(?:►\\s*)?\\[?(?<start>(?:[0-9]+:){1,2}[0-9]+)\\]?(?:\\s*-\\s*)?(?<end>(?:[0-9]+:){1,2}[0-9]+)?(?:\\s*-\\s*|\\s*[:]\\s*)?(?<title>.*)(?=\\n|$)",
 | 
				
			||||||
 | 
					            "(?<=\\n|^)\\s*(?:►\\s*)?\\[?(?<start>(?:[0-9]+:){1,2}[0-9]+)\\]?\\s*[-:]?\\s*(?<title>.+)(?=\\n|$)",
 | 
				
			||||||
 | 
					            "(?<=\\n|^)(?<index>[0-9]+\\.\\s)(?<title>.+?)(?:\\s*-\\s*)?(?<start>(?:[0-9]+:){1,2}[0-9]+)(?=\\n|$)",
 | 
				
			||||||
 | 
					            "(?<=\\n|^)(?<title>.+?):\\s*\\((?<start>(?:[0-9]+:){1,2}[0-9]+)\\)(?=\\n|$)"
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            guard let titleSubstringRange = Range(titleRange, in: description),
 | 
					        for pattern in patterns {
 | 
				
			||||||
                  let startSubstringRange = Range(startRange, in: description) else { return nil }
 | 
					            guard let chaptersRegularExpression = try? NSRegularExpression(pattern: pattern, options: .caseInsensitive) else { continue }
 | 
				
			||||||
 | 
					            let chapterLines = chaptersRegularExpression.matches(in: description, range: NSRange(description.startIndex..., in: description))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            let titleCapture = String(description[titleSubstringRange])
 | 
					            if !chapterLines.isEmpty {
 | 
				
			||||||
            let startCapture = String(description[startSubstringRange])
 | 
					                return chapterLines.compactMap { line in
 | 
				
			||||||
            let startComponents = startCapture.components(separatedBy: ":")
 | 
					                    let titleRange = line.range(withName: "title")
 | 
				
			||||||
            guard startComponents.count <= 3 else { return nil }
 | 
					                    let startRange = line.range(withName: "start")
 | 
				
			||||||
 | 
					                    guard let titleSubstringRange = Range(titleRange, in: description),
 | 
				
			||||||
 | 
					                          let startSubstringRange = Range(startRange, in: description)
 | 
				
			||||||
 | 
					                    else {
 | 
				
			||||||
 | 
					                        return nil
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    let titleCapture = String(description[titleSubstringRange]).trimmingCharacters(in: .whitespaces)
 | 
				
			||||||
 | 
					                    let startCapture = String(description[startSubstringRange])
 | 
				
			||||||
 | 
					                    let startComponents = startCapture.components(separatedBy: ":")
 | 
				
			||||||
 | 
					                    guard startComponents.count <= 3 else { return nil }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var hours: Double?
 | 
					                    var hours: Double?
 | 
				
			||||||
            var minutes: Double?
 | 
					                    var minutes: Double?
 | 
				
			||||||
            var seconds: Double?
 | 
					                    var seconds: Double?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if startComponents.count == 3 {
 | 
					                    if startComponents.count == 3 {
 | 
				
			||||||
                hours = Double(startComponents[0])
 | 
					                        hours = Double(startComponents[0])
 | 
				
			||||||
                minutes = Double(startComponents[1])
 | 
					                        minutes = Double(startComponents[1])
 | 
				
			||||||
                seconds = Double(startComponents[2])
 | 
					                        seconds = Double(startComponents[2])
 | 
				
			||||||
            } else if startComponents.count == 2 {
 | 
					                    } else if startComponents.count == 2 {
 | 
				
			||||||
                minutes = Double(startComponents[0])
 | 
					                        minutes = Double(startComponents[0])
 | 
				
			||||||
                seconds = Double(startComponents[1])
 | 
					                        seconds = Double(startComponents[1])
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    guard var startSeconds = seconds else { return nil }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    startSeconds += (minutes ?? 0) * 60
 | 
				
			||||||
 | 
					                    startSeconds += (hours ?? 0) * 60 * 60
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    return .init(title: titleCapture, start: startSeconds)
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					 | 
				
			||||||
            guard var startSeconds = seconds else { return nil }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if let minutes {
 | 
					 | 
				
			||||||
                startSeconds += 60 * minutes
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if let hours {
 | 
					 | 
				
			||||||
                startSeconds += 60 * 60 * hours
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            return .init(title: titleCapture, start: startSeconds)
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        return []
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user