1

I have a relatively complex regex that I need to run in Swift. Originally was:

"typedef\W+struct\W+{([^}]*)}\W+(\w+);"

You can see the pattern working in JS here.

To make it compile in Swift I escaped the backslashes to:

"typedef\\W+struct\\W+{([^}]*)}\\W+(\\w+);"

On runtime the expression fails to compile with 2048 error. I tried escaping other characters too and tried also escapedPatternForString but without luck. Is there a script to convert JS regexs to Swift? Thanks!

Nuthinking
  • 1,211
  • 2
  • 13
  • 32

1 Answers1

2

You need to escape both { and } that are outside of a character class:

let rx = "typedef\\W+struct\\W+\\{([^}]*)\\}\\W+(\\w+);"

A quick demo:

let rx = "typedef\\W+struct\\W+\\{([^}]*)\\}\\W+(\\w+);"
let str = "typedef: struct { something } text;"
print(str.range(of: rx, options: .regularExpression) != nil) 
// => true

When the { and } are inside a character class they may stay unescaped (as in [^}]).

Using this code (answer by Confused Vorlon), you may get the first match with all capturing groups:

extension NSTextCheckingResult {
    func groups(testedString:String) -> [String] {
        var groups = [String]()
        for i in  0 ..< self.numberOfRanges
        {
            let group = String(testedString[Range(self.range(at: i), in: testedString)!])
            groups.append(group)
        }
        return groups
    }
}

let str = "typedef: struct { something } text;"
let rx = "typedef\\W+struct\\W+\\{([^}]*)\\}\\W+(\\w+);"
let MyRegex = try! NSRegularExpression(pattern: rx)
if let match = MyRegex.firstMatch(in: str, range: NSMakeRange(0, str.count)) {
     let groups = match.groups(testedString: str)
     print(groups)
}
// => ["typedef: struct { something } text;", " something ", "text"]
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • @Nuthinking There are a lot of questions regarding getting captures from matches. See [this answer](https://stackoverflow.com/a/40040472/3832970), for example. Do you need to get just the contents of a single capturing group? – Wiktor Stribiżew Feb 08 '19 at 18:13