swiftregexswiftsoup

Find & Replace String using regex


I need to extract data from a string which is returned from a website with POST request; I am parsing the data with SwiftSoup library. I have selected the list items using a CSS selector:

let iconsList: Element = try doc.select("ul.icons-list").first()!

which returns html like this:

<ul class="icons-list"> 
   <li><strong>Label 1:</strong> Value 1 (Some text) </li> 
   <li><strong>Label 2:</strong> Value 2</li> 
   <li><strong>Label 3:</strong> Value 3</li> 
   <li><strong>Label 4:</strong> Value 4 </li> 
   <li><strong>Label 5:</strong> Value 5</li> 
</ul>

Now I need to extract labels and values and store inside array or maybe separate variables. I have tried Regex like shown below (didn't work, maybe wrong regex):

let result = "This <strong>Needs to be removed</strong> is my string"
let regex = try! NSRegularExpression(pattern: "<strong>(.*)</strong>", options: .caseInsensitive)
var newStr = regex.stringByReplacingMatches(in: result, options: [], range: NSRange(0..<str.utf16.count), withTemplate: "")
print(newStr)

And also tried SwiftSoup selector like:

var labelFirst = try doc.select("ul.icons-list li:nth-child(1)")

But it also returns HTML result. So, I need to use regex in both cases. How can this be done?

Another Question: When I select icons-list class using SwiftSoup ".select" selector. If there's an exception then how do I handle that? Currently, I have this code but it's not working. And what if I want to handle multiple try blocks inside this block?

do{
      let doc: Document = try SwiftSoup.parse(responseString!)
      let iconsList: Element = try doc.select("ul.icons-list").first()!
      print(iconsList)
  }catch Exception.Error( _, let message){
      print("icons list not found "+message)
  }catch{
      print("error")
  }

Solution

  • I was able to figure out myself. Here's how I've done that:

    var res = "<ul class=\"icons-list\"><li><strong>Label 1:</strong> Value 1 (Some text) </li></ul>"
    
    extension String {
      func capturedGroups(withRegex pattern: String) -> [String] {
        var results = [String]()
    
        var regex: NSRegularExpression
        do {
            regex = try NSRegularExpression(pattern: pattern, options: [])
        } catch {
            return results
        }
    
        let matches = regex.matches(in: self, options: [], range: NSRange(location:0, length: self.characters.count))
    
        guard let match = matches.first else { return results }
    
        let lastRangeIndex = match.numberOfRanges - 1
        guard lastRangeIndex >= 1 else { return results }
    
        for i in 1...lastRangeIndex {
            let capturedGroupIndex = match.rangeAt(i)
            let matchedString = (self as NSString).substring(with: capturedGroupIndex)
            results.append(matchedString)
        }
    
        return results
      }
    }
    
    let label1 = res.capturedGroups(withRegex: "<strong>(.*)</strong>")
    let value1 = res.capturedGroups(withRegex: "</strong>(.*)</li>")
    
    print("\(label1[0]): \(value1[0])")
    //Output: Label 1:  Value 1 (Some text) 
    

    I would still appreciate if someone gives me better way OR improve my function!