Last active
August 21, 2021 16:50
-
-
Save carlynorama/35023ab68a81d56342651b1c1e926cd7 to your computer and use it in GitHub Desktop.
Parsing fractions from text
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
let fractionRegExPattern = #"(?<neg>-?){0,1}(?:\s){0,1}(?:(?<whole>\d+)\s)?(?<numerator>\d+)\/(?<denominator>\d+)"# | |
func parseResult(_ match:NSTextCheckingResult, canidateString:String) -> (Int?, Int, Int) { | |
var mulitplier = 1 | |
var wholeNumber: Int? | |
var numerator: Int? | |
var denominator: Int? | |
if canidateString[(Range(match.range(withName: "neg"), in: canidateString)!)] == "-" { | |
mulitplier = -1 | |
print("negative!") | |
} | |
if let wholeNumberRange = Range(match.range(withName: "whole"), in: canidateString) { | |
wholeNumber = Int(canidateString[wholeNumberRange]) | |
if wholeNumber != nil { | |
wholeNumber = wholeNumber! * mulitplier | |
} | |
} | |
if let numeratorRange = Range(match.range(withName: "numerator"), in: canidateString) { | |
numerator = Int(canidateString[numeratorRange]) | |
if wholeNumber == nil { | |
numerator = numerator! * mulitplier | |
} | |
} | |
if let denominatorRange = Range(match.range(withName: "denominator"), in: canidateString) { | |
denominator = Int(canidateString[denominatorRange]) | |
} | |
if numerator == nil || denominator == nil { | |
fatalError("how did they not get found???!!!") | |
} | |
return (whole:wholeNumber, numerator:numerator!, denominator:denominator!) | |
} | |
func findAll(in canidateString:String) -> [(whole:Int?, numerator:Int, denominator:Int)] { | |
let regex = try? NSRegularExpression(pattern: fractionRegExPattern, options: .caseInsensitive) | |
var foundFractions:[(whole:Int?, numerator:Int, denominator:Int)] = [] | |
if let matches = regex?.matches(in: canidateString, options: [], range: NSRange(location: 0, length: canidateString.utf16.count)) { | |
for m in 0..<matches.count { | |
foundFractions.append(parseResult(matches[m], canidateString: canidateString)) | |
} | |
} | |
return foundFractions | |
} | |
func findFirst(in canidateString:String) -> (whole:Int?, numerator:Int, denominator:Int)? { | |
guard let regex = try? NSRegularExpression(pattern: fractionRegExPattern, options: .caseInsensitive) else { | |
print("bad regex") | |
return nil | |
} | |
if let match = regex.firstMatch(in: canidateString, options: [], range: NSRange(location: 0, length: canidateString.utf16.count)) { | |
return parseResult(match, canidateString: canidateString) | |
} | |
return nil | |
} | |
let testStrings = [ | |
"8 3/4", | |
"-5 32/12 in", | |
"-5/7", | |
"- 7 3/32", | |
"approx. - 9/12", | |
"12", | |
"Between 1/4 and 3/16th" | |
] | |
for string in testStrings { | |
print(findFirst(string)) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment