Trying to work out a regular expression. The output is sporadic. Each capture group has at least one nil value in a varying place for each of my three named capture groups and sometimes the capture groups are out of order. Have checked SO for a solution but no luck so far, so thought I'd ask.
Basically, my text file contains a bunch of hex's that combine to form gradients. The relevant stuff I need to scrape within the file looks like this, repeating periodically throughout our file:
002 Tropic Thunder
#a18cd2|#fbc4eb
First, I have been reading in the rtf file:
if let rtfPath = Bundle.main.url(forResource: "mytextfile", withExtension: "rtf") {
do {
let attributedStringWithRtf: NSAttributedString = try NSAttributedString(url: rtfPath, options: [NSAttributedString.DocumentReadingOptionKey.documentType: NSAttributedString.DocumentType.rtf], documentAttributes: nil)
self.testString = attributedStringWithRtf
} catch let error {
print("Got an error \(error)")
}
}
let myString = self.testString?.string
Next, I create the pattern, call my function, and print the result:
do {
pattern = try NSRegularExpression(pattern: "[0-9]{3}\\s*(?<gradientName>[a-zA-Z]{2,11}\\s[a-zA-Z]{2,11})\\s*(?<hexCode1>#[0-9a-fA-F]{6})|(?<hexCode2>#[0-9a-fA-F]{6})")
} catch {
print(error)
}
let result = namedCaptureGroupsInMatches(of: pattern!, against: myString!)
print(result)
My function looks like this:
func namedCaptureGroupsInMatches(of regularExpression:NSRegularExpression, against string:String) -> [[String:Substring?]] {
let names = namedCaptureGroups(inRegularExpression: regularExpression)
let ms = regularExpression.matches(in: string, options: [],
range:NSRange(string.startIndex..<string.endIndex,
in:string))
return ms.map({ (tcr:NSTextCheckingResult) -> [String:Substring?] in
let keyvalues = names.map({ (name:String) -> (String,Substring?) in
let captureGroupRange = tcr.range(withName: name)
if captureGroupRange.location == NSNotFound {
return (name,nil)
} else {
return (name,string[Range(captureGroupRange, in: string)!])
}
})
return Dictionary(uniqueKeysWithValues: keyvalues)
})
}
func namedCaptureGroups(inRegularExpression regularExpression:NSRegularExpression) -> [String]
{
let regexString = regularExpression.pattern
let captureGroupNames = try! NSRegularExpression(pattern: "\\(\\?\\<(\\w+)\\>", options: [])
let groupNameMatches = captureGroupNames.matches(in: regexString, options: [],
range: NSRange(regexString.startIndex..<regexString.endIndex,
in:regexString))
let names = groupNameMatches.map { (textCheckingResult) -> String in
return (regexString as NSString).substring(with: textCheckingResult.range(at: 1))
}
return names
}
Any ideas?