用于匹配锚标记及其 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¶m2=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
}
}
首先,你需要学习NSRegularExpression
的pattern
的基本语法:
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¶m2=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¶m2=22"]
请记住,我上面的 pattern
可能会错误地检测到格式不正确的 a-tags 或遗漏一些嵌套结构,而且它缺乏与 HTML 字符实体一起使用的功能...
如果你想让你的代码更健壮和通用,你最好考虑采用 ColGraff 和 Rob 建议的 HTML 解析器。
我想 运行 通过具有多个锚标记的 html 字符串进行正则表达式,并构建 link 文本与其 href url.
<p>This is a simple text with some embedded <a href="http://example.com/link/to/some/page?param1=77¶m2=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
}
}
首先,你需要学习NSRegularExpression
的pattern
的基本语法:
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¶m2=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¶m2=22"]
请记住,我上面的 pattern
可能会错误地检测到格式不正确的 a-tags 或遗漏一些嵌套结构,而且它缺乏与 HTML 字符实体一起使用的功能...
如果你想让你的代码更健壮和通用,你最好考虑采用 ColGraff 和 Rob 建议的 HTML 解析器。