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

Popular posts from this blog

java - Run spring boot application error: Cannot instantiate interface org.springframework.context.ApplicationListener -

reactjs - React router and this.props.children - how to pass state to this.props.children -

Excel VBA "Microsoft Windows Common Controls 6.0 (SP6)" Location Changes -