【问题标题】:Extract link from href in Swift从 Swift 中的 href 中提取链接
【发布时间】:2019-05-09 03:20:45
【问题描述】:

假设我有一个这样的 html 链接:

<a href = "https://mitsui-shopping-park.com/lalaport/koshien/" target="_blank"> https://mitsui-shopping-park.com/lalaport / koshien / </a>

我要提取:

<a href = "THIS LINK" target="_blank"> NOT THIS LINK </a> 

我试过了:someString.replacingOccurrences(of: "&lt;[^&gt;]+&gt;", with: "", options: .regularExpression, range: nil) 但这给了我:

<a href = "NOT THIS LINK" target="_blank"> BUT THIS LINK </a>

请帮忙。

【问题讨论】:

  • 这里有一些关于解析 HTML 的有用信息:stackoverflow.com/questions/31080818/…
  • 当前接受的答案是"href = "https://mitsui-shopping-park.com/lalaport/koshien/",而不是实际的链接,这是所需的输出吗?
  • 在我的情况下是的,这是所需的输出。

标签: swift


【解决方案1】:

不需要正则表达式,您可以使用属性字符串的link 属性。

首先,让我们使用this 扩展名:

extension String{
    func convert2Html() -> NSAttributedString {

        guard let data = data(using: .utf8) else { return NSAttributedString() }

        do {
            let htmlAttrib = NSAttributedString.DocumentType.html
            return try NSAttributedString(data: data,
                                          options: [.documentType : htmlAttrib],
                                          documentAttributes: nil)
        } catch {
            return NSAttributedString()
        }
    }
}

转换这个String:

let html = "<a href = \"https://mitsui-shopping-park.com/lalaport/koshien/\" target=\"_blank\"> https://mitsui-shopping-park.com/lalaport / koshien / </a>"

NSAttributedString:

let attrib = html.convert2Html()

然后以这种方式提取链接:

let link = attrib.attribute(.link, at: 0, effectiveRange: nil)

if let url = link as? NSURL, let href = url.absoluteString {
    print(href)  //https://mitsui-shopping-park.com/lalaport/koshien/
}

【讨论】:

    【解决方案2】:

    这是获取href=" 和结束" 之间的值的一种可能解决方案。这仅适用于字符串中的一个 href。

    let html = "<a href = \"https://mitsui-shopping-park.com/lalaport/koshien/\" target=\"_blank\"> https://mitsui-shopping-park.com/lalaport / koshien / </a>"
    
    if let hrefRange = html.range(of: "(?:href\\s*=\\s*\")[^\"]*(?:\")", options: .regularExpression) {
        let href = html[hrefRange]
        print(href)
    } else {
        print("There is no href")
    }
    

    让我们分解那个正则表达式:

    首先,让我们删除 RE 中所需的额外 \ 使其成为值 Swift 字符串。这给我们留下了:

    (?:href\s*=\s*")[^"]*(?:")
    

    这包括三个主要部分:

    (?:href\s*=\s*") - the href, optional space, =, optional space, and opening quote
    [^"]* - the actual URL - everything that isn't a quote
    (?:") - the close quote
    

    (?: ) 语法意味着里面的东西不会是返回字符串的一部分。

    【讨论】:

      【解决方案3】:

      NSRegularExpression.matches 用于正则表达式的捕获组功能。我总是使用这种方便的扩展方法:

      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.count))
      
              guard let match = matches.first else { return results }
              let lastRangeIndex = match.numberOfRanges - 1
              guard lastRangeIndex >= 1 else { return results }
      
              for i in 0...lastRangeIndex {
                  let capturedGroupIndex = match.range(at: i)
                  if(capturedGroupIndex.length>0)
                  {
                      let matchedString = (self as NSString).substring(with: capturedGroupIndex)
                      results.append(matchedString)
                  }
                  else
                  {
                      results.append(nil)
                  }
              }
      
              return results
          }
      }
      
      var html = """
      <a href = "https://mitsui-shopping-park.com/lalaport/koshien/" target="_blank"> https://mitsui-shopping-park.com/lalaport / koshien / </a>
      """
      print(html.capturedGroups(withRegex: "href\\s*=\\s*\"([^\"]+)\"")[1])
      

      【讨论】:

      • 为什么是可选字符串数组?
      • 我记得我从 SO 帖子中复制了这个并将其放入我的项目代码库并继续使用它。大声笑从没想过。是的,这没有任何意义。
      猜你喜欢
      • 1970-01-01
      • 2015-10-29
      • 2021-06-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多