0

I am looking to extract and print strings using swift on regex but am stuck on how to do it. I am new to swift and regex on swift so having a hard time figuring it out

In the below example I want to print 62AD and 21BC (Whatever is inside the square brackets). I could only come up with this code but this doesnt extract anything and gives a nil value. The newline character and the quotes are part of the string

let output = "\"Living Room\" [62AD]\n Hub \"Living Room\" [21BC]:"
let range = NSRange(output.startIndex..<output.endIndex,in: output)
let patternToMatch1 = "\"Living Room\" [.*]+\n"
let patternToMatch2 = "Hub \"Living Room\" [^:]+:"
let captureRegex1 = try! NSRegularExpression(pattern: patternToMatch1, options: [])
let captureRegex2 = try! NSRegularExpression(pattern: patternToMatch2, options: [])
let matches1 = captureRegex1.matches(in: output,options: [],range: range)
guard let match1 = matches1.first else {
         throw NSError(domain: "", code: 0, userInfo: nil)
}
print("\(String(describing:match1))")

let matches2 = captureRegex2.matches(in: output,options: [],range: range)
guard let match2 = matches2.first else {
         throw NSError(domain: "", code: 0, userInfo: nil)
}
print("\(String(describing:match2))")
   
SB26
  • 225
  • 1
  • 6
  • 17
  • "this hasnt been working" How has it not been working? – El Tomato Jul 29 '21 at 08:57
  • Note `[` is a special char, you will at least need to escape that, `\\[` in the string literal you have. However, you have not explained the problem with this code. – Wiktor Stribiżew Jul 29 '21 at 08:58
  • Side note: you should not use `String(describing:)` but use the normal `String()` initializer, or string interpolation, instead. – Eric Aya Jul 29 '21 at 08:59
  • updated the description. There are a lot of things i tried and result returned nil in most cases – SB26 Jul 29 '21 at 09:02
  • Simply using `\"Living Room\" \\[.*\\]+\n` solved the issue for me – Schottky Jul 29 '21 at 09:07
  • 1
    Use the example [in this answer](https://stackoverflow.com/q/58634799/2227743) with this regex: `\\[.*?(.*?)\\]`. The result will be `["62AD", "21BC"]` – Eric Aya Jul 29 '21 at 09:08

1 Answers1

0

Combine your fixed regex with this solution:

import Foundation
func matches(for regex: String, in text: String) -> [String] {
    do {
        let regex = try NSRegularExpression(pattern: regex)
        let nsString = text as NSString
        let results = regex.matches(in: text, range: NSRange(location: 0, length: nsString.length))
        return results.map { nsString.substring(with: $0.range(at: 1))}
    } catch let error {
        print("invalid regex: \(error.localizedDescription)")
        return []
    }
}
let output = "\"Living Room\" [62AD]\n Hub \"Living Room\" [21BC]:"
let patternToMatch1 = "\"Living Room\"\\s*\\[(.*?)]"
print(matches(for: patternToMatch1, in:output))

Results: ["62AD", "21BC"]

See regex proof.

EXPLANATION

--------------------------------------------------------------------------------
  "Living Room"            '"Living Room"'
--------------------------------------------------------------------------------
  \s*                      whitespace (\n, \r, \t, \f, and " ") (0 or
                           more times (matching the most amount
                           possible))
--------------------------------------------------------------------------------
  \[                       '['
--------------------------------------------------------------------------------
  (                        group and capture to \1:
--------------------------------------------------------------------------------
    .*?                      any character except \n (0 or more times
                             (matching the least amount possible))
--------------------------------------------------------------------------------
  )                        end of \1
--------------------------------------------------------------------------------
  ]                        ']'
Ryszard Czech
  • 18,032
  • 4
  • 24
  • 37