用于匹配锚标记及其 href 的正则表达式

Regex to match anchor tag and its href

我想 运行 通过具有多个锚标记的 html 字符串进行正则表达式,并构建 link 文本与其 href url.

<p>This is a simple text with some embedded <a href="http://example.com/link/to/some/page?param1=77&param2=22">links</a>. This is a <a href="https://exmp.le/sample-page/?uu=1">different link</a>.

如何一次提取 <a> 标签的文本和 href?

编辑:

func extractLinks(html: String) -> Dictionary<String, String>? {

    do {
        let regex = try NSRegularExpression(pattern: "/<([a-z]*)\b[^>]*>(.*?)</>/i", options: [])
        let nsString = html as NSString
        let results = regex.matchesInString(html, options: [], range: NSMakeRange(0, nsString.length))
        return results.map { nsString.substringWithRange([=10=].range)}
    } catch let error as NSError {
        print("invalid regex: \(error.localizedDescription)")
        return nil
    }
}

首先,你需要学习NSRegularExpressionpattern的基本语法:

  • pattern不包含分隔符
  • pattern不包含修饰符,需要传递options
  • 等信息
  • 当你想使用元字符 \ 时,你需要将其转义为 Swift 字符串中的 \

所以,创建 NSRegularExpression 实例的行应该是这样的:

let regex = try NSRegularExpression(pattern: "<([a-z]*)\b[^>]*>(.*?)</\1>", options: .caseInsensitive)

但是,您可能已经知道,您的模式不包含任何代码来匹配 href 或捕获它的值。

类似这样的方法适用于您的示例 html:

let pattern = "<a\b[^>]*\bhref\s*=\s*(\"[^\"]*\"|'[^']*')[^>]*>((?:(?!</a).)*)</a\s*>"
let regex = try! NSRegularExpression(pattern: pattern, options: .caseInsensitive)
let html = "<p>This is a simple text with some embedded <a\n" +
    "href=\"http://example.com/link/to/some/page?param1=77&param2=22\">links</a>.\n" +
    "This is a <a href=\"https://exmp.le/sample-page/?uu=1\">different link</a>."
let matches = regex.matches(in: html, options: [], range: NSRange(0..<html.utf16.count))
var resultDict: [String: String] = [:]
for match in matches {
    let hrefRange = NSRange(location: match.rangeAt(1).location+1, length: match.rangeAt(1).length-2)
    let innerTextRange = match.rangeAt(2)
    let href = (html as NSString).substring(with: hrefRange)
    let innerText = (html as NSString).substring(with: innerTextRange)
    resultDict[innerText] = href
}
print(resultDict)
//->["different link": "https://exmp.le/sample-page/?uu=1", "links": "http://example.com/link/to/some/page?param1=77&param2=22"]

请记住,我上面的 pattern 可能会错误地检测到格式不正确的 a-tags 或遗漏一些嵌套结构,而且它缺乏与 HTML 字符实体一起使用的功能...

如果你想让你的代码更健壮和通用,你最好考虑采用 ColGraff 和 Rob 建议的 HTML 解析器。