ios - Named capture groups in NSRegularExpression - get a range's group's name -
apple says nsregularexpression based on icu regular expression library: https://developer.apple.com/library/ios/documentation/foundation/reference/nsregularexpression_class/
the pattern syntax supported specified icu. icu regular expressions described @ http://userguide.icu-project.org/strings/regexp.
that page (on icu-project.org) claims named capture groups supported, using same syntax .net regular expressions:
(?<name>...)
named capture group.<angle brackets>
literal - appear in pattern.
i have written program gets single match multiple ranges seem correct - though each range returned twice (for reasons unknown) - information have range's index , text range.
for example, regex: ^(?<foo>foo)\.(?<bar>bar)\.(?<bar2>baz)$
test string foo.bar.baz
gives me these results:
idx start length text 0 0 11 foo.bar.baz 1 0 3 foo 2 4 3 bar 3 8 3 baz
is there way know "baz
" came capture-group bar2
?
i facing same issue , ended backing own solution. feel free comment or improve ;-)
extension nsregularexpression { typealias groupnamessearchresult = (nstextcheckingresult, nstextcheckingresult, int) private func textcheckingresultsofnamedcapturegroups() throws -> [string:groupnamessearchresult] { var groupnames = [string:groupnamessearchresult]() let greg = try nsregularexpression(pattern: "^\\(\\?<([\\w\\a_-]*)>.*\\)$", options: nsregularexpressionoptions.dotmatcheslineseparators) let reg = try nsregularexpression(pattern: "\\([^\\(\\)]*\\)", options: nsregularexpressionoptions.dotmatcheslineseparators) let m = reg.matchesinstring(self.pattern, options: nsmatchingoptions.withtransparentbounds, range: nsrange(location: 0, length: self.pattern.utf16.count)) (n,g) in m.enumerate() { let gstring = self.pattern.substringwithrange(g.rangeatindex(0).torange()!) print(self.pattern.substringwithrange(g.rangeatindex(0).torange()!)) let gmatch = greg.matchesinstring(gstring, options: nsmatchingoptions.anchored, range: nsrange(location: 0, length: gstring.utf16.count)) if gmatch.count > 0{ groupnames[gstring.substringwithrange(gmatch[0].rangeatindex(1).torange()!)] = (g,gmatch[0],n) } } return groupnames } func indexofnamedcapturegroups() throws -> [string:int] { var groupnames = [string:int]() (name,(_,_,n)) in try self.textcheckingresultsofnamedcapturegroups() { groupnames[name] = n + 1 } //print(groupnames) return groupnames } func rangesofnamedcapturegroups(match:nstextcheckingresult) throws -> [string:range<int>] { var ranges = [string:range<int>]() (name,(_,_,n)) in try self.textcheckingresultsofnamedcapturegroups() { ranges[name] = match.rangeatindex(n+1).torange() } return ranges } }
here usage example:
let node = "'test_literal'" let regex = try nsregularexpression(pattern: "^(?<delimiter>'|\")(?<value>.*)(?:\\k<delimiter>)$", options: nsregularexpressionoptions.dotmatcheslineseparators) let match = regex.matchesinstring(node, options: nsmatchingoptions.anchored, range: nsrange(location: 0,length: node.utf16.count)) if match.count > 0 { let ranges = try regex.rangesofnamedcapturegroups(match[0]) guard let range = ranges["value"] else { } }
Comments
Post a Comment