this repo has no description
at main 55 lines 2.7 kB view raw
1import Foundation 2 3public enum TextParsing { 4 /// Removes ANSI escape sequences so regex parsing works on colored terminal output. 5 public static func stripANSICodes(_ text: String) -> String { 6 // CSI sequences: ESC [ ... ending in 0x400x7E 7 let pattern = #"\u001B\[[0-?]*[ -/]*[@-~]"# 8 guard let regex = try? NSRegularExpression(pattern: pattern, options: []) else { return text } 9 let range = NSRange(text.startIndex..<text.endIndex, in: text) 10 return regex.stringByReplacingMatches(in: text, options: [], range: range, withTemplate: "") 11 } 12 13 public static func firstNumber(pattern: String, text: String) -> Double? { 14 guard let regex = try? NSRegularExpression(pattern: pattern, options: [.caseInsensitive]) else { return nil } 15 let range = NSRange(text.startIndex..<text.endIndex, in: text) 16 guard let match = regex.firstMatch(in: text, options: [], range: range), 17 match.numberOfRanges >= 2, 18 let r = Range(match.range(at: 1), in: text) else { return nil } 19 let raw = text[r].replacingOccurrences(of: ",", with: "") 20 return Double(raw) 21 } 22 23 public static func firstInt(pattern: String, text: String) -> Int? { 24 guard let v = firstNumber(pattern: pattern, text: text) else { return nil } 25 return Int(v) 26 } 27 28 public static func firstLine(matching pattern: String, text: String) -> String? { 29 guard let regex = try? NSRegularExpression(pattern: pattern, options: [.caseInsensitive]) else { return nil } 30 let range = NSRange(text.startIndex..<text.endIndex, in: text) 31 guard let match = regex.firstMatch(in: text, options: [], range: range), 32 let r = Range(match.range(at: 0), in: text) else { return nil } 33 return String(text[r]) 34 } 35 36 public static func percentLeft(fromLine line: String) -> Int? { 37 guard let pct = firstInt(pattern: #"([0-9]{1,3})%\s+left"#, text: line) else { return nil } 38 return pct 39 } 40 41 public static func resetString(fromLine line: String) -> String? { 42 guard let regex = try? NSRegularExpression(pattern: #"resets?\s+(.+)"#, options: [.caseInsensitive]) else { 43 return nil 44 } 45 let range = NSRange(line.startIndex..<line.endIndex, in: line) 46 guard let match = regex.firstMatch(in: line, options: [], range: range), 47 match.numberOfRanges >= 2, 48 let r = Range(match.range(at: 1), in: line) 49 else { 50 return nil 51 } 52 // Return the tail text only (drop the "resets" prefix). 53 return String(line[r]).trimmingCharacters(in: .whitespacesAndNewlines) 54 } 55}