【发布时间】:2019-01-17 07:24:00
【问题描述】:
我正在使用名为 Kanna 的解析库获取网页的 HTML 代码。基本上精简版是这样的。
<!DOCTYPE html>
<html lang="en" class="no-js not-logged-in client-root">
<head>
<meta charset="utf-8">
</head>
<body>
<script type="text/javascript">
window._sharedData = {
// Some JSON
};
</script>
<script type="text/javascript">
// Javascript code
</script>
<script type="text/javascript">
// More Javascript code
</script>
</body>
</html>
body 中有多个script 标签。我想使用名为window._sharedData 的变量访问那个变量并提取它的值,它是一个 JSON 字典。
我尝试使用正则表达式,但它返回 nil。也许我的模式有问题?
if let doc = try? HTML(url: mixURL, encoding: .utf8), let body = doc.body, let htmlText = body.text {
let range = NSRange(location: 0, length: htmlText.utf8.count)
let regex = try! NSRegularExpression(pattern: "/<script type=\"text/javascript\">window._sharedData = (.*)</script>/")
let s = regex.firstMatch(in: htmlText, options: [], range: range)
print(s)
}
或者有更好的方法吗?
【问题讨论】:
-
删除正则表达式模式中的第一个和最后一个
/。在模式开始处添加(?s)。将.*替换为.*?。在window之前添加\\s*。并转义文字.请参阅 this demo。 -
@WiktorStribiżew 非常感谢!我试过你的模式。但是我不得不做出一些改变,因为在 Swift 中我不得不转义
` like this\`。所以完整的模式看起来像这样(?s)<script type=\"text/javascript\">\\s*window\\._sharedData = (.*?)</script>。但不知何故它不匹配:/ -
是的,要定义
\,您必须在字符串文字中使用\\。这不是对正则表达式的更改,而是您在 Swift 代码中编写该字符串的方式。怎么没有?这就是它的样子:pattern: "(?s)<script type=\"text/javascript\">\\s*window\\._sharedData = (.*?)</script>"。如果它不起作用,则问题出在您的代码上。请注意,Swift 正则表达式适用于 UTF16 编码的字符串。尝试用htmlText.utf16.count替换htmlText.utf8.count -
好吧,我已经尝试了我最初的建议,它返回
Optional(<_NSRegularExpressionNSTextCheckingResultResult: 0x00005582ba121120>)。 -
@WiktorStribiżew 是的。当我像上面的代码一样将 html 作为字符串尝试时,它确实有效。但是由于某种原因,当我使用我使用该库动态获得的 html 代码时,它不会。让我分享一下我的demo project。
标签: javascript html ios swift regex