2

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")
  }
2
  • In the first case, you could try "(?s)<strong>(.*?)</strong>" and replace with $1. Commented Jun 8, 2017 at 8:52
  • thanks but that didn't work! :( Commented Jun 9, 2017 at 17:31

1 Answer 1

1

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!

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.