使用正则表达式从HTML提取关联的年份、金额及余额数组
提取指定JS数组并关联对应数据的解决方案
问题分析
你之前的正则仅匹配数字/数字组,未关联数组变量名,因此无法区分数据属于years/amounts/balances中的哪一个。需要针对每个目标数组编写精准匹配变量定义+数组内容的正则,再提取对应元素。
正则方案
针对三个数组的不同数据类型(字符串年份、浮点金额、整数余额),分别使用如下正则:
- 匹配
years数组:var years = \['([^']+(?:',\s*'[^']+)*)'\];
捕获组1会得到用, '分隔的年份字符串(比如2020', '2021', '2022) - 匹配
amounts数组:var amounts = \[([\d.]+(?:,\s*[\d.]+)*)\];
捕获组1会得到用,分隔的浮点数字符串(比如1269.2358, 1456.557, 1546.8768) - 匹配
balances数组:var balances = \[([\d]+(?:,\s*[\d]+)*)\];
捕获组1会得到用,分隔的整数字符串(比如3484626, 3683646, 3683070)
Swift 实现代码
以下是完整的Swift代码示例,包含正则匹配、元素提取和类型转换:
import Foundation // 假设你已经从HTML中提取到的目标JS代码片段 let jsCode = """ $(document).ready(function() { var years = ['2020','2021','2022']; var currentView = 0; var amounts = [1269.2358,1456.557,1546.8768]; var balances = [3484626,3683646,3683070]; rest of the html code """ // 1. 提取years数组 func extractYears(from jsCode: String) -> [Int]? { let pattern = #"var years = \['([^']+(?:',\s*'[^']+)*)'\];"# guard let regex = try? NSRegularExpression(pattern: pattern), let match = regex.firstMatch(in: jsCode, range: NSRange(jsCode.startIndex..., in: jsCode)), let captureRange = Range(match.range(at: 1), in: jsCode) else { return nil } let yearStrings = String(jsCode[captureRange]).split(separator: "', '").map(String.init) return yearStrings.compactMap(Int.init) } // 2. 提取amounts数组 func extractAmounts(from jsCode: String) -> [Double]? { let pattern = #"var amounts = \[([\d.]+(?:,\s*[\d.]+)*)\];"# guard let regex = try? NSRegularExpression(pattern: pattern), let match = regex.firstMatch(in: jsCode, range: NSRange(jsCode.startIndex..., in: jsCode)), let captureRange = Range(match.range(at: 1), in: jsCode) else { return nil } let amountStrings = String(jsCode[captureRange]).split(separator: ", ").map(String.init) return amountStrings.compactMap(Double.init) } // 3. 提取balances数组 func extractBalances(from jsCode: String) -> [Int]? { let pattern = #"var balances = \[([\d]+(?:,\s*[\d]+)*)\];"# guard let regex = try? NSRegularExpression(pattern: pattern), let match = regex.firstMatch(in: jsCode, range: NSRange(jsCode.startIndex..., in: jsCode)), let captureRange = Range(match.range(at: 1), in: jsCode) else { return nil } let balanceStrings = String(jsCode[captureRange]).split(separator: ", ").map(String.init) return balanceStrings.compactMap(Int.init) } // 使用示例 if let years = extractYears(from: jsCode) { print("提取的年份:\(years)") } if let amounts = extractAmounts(from: jsCode) { print("提取的金额:\(amounts)") } if let balances = extractBalances(from: jsCode) { print("提取的余额:\(balances)") }
关键说明
- 正则中的
(?:...)是非捕获组,用来匹配重复的元素分隔模式,不会额外生成无用的捕获组 - 使用
compactMap处理类型转换,自动过滤转换失败的元素(比如格式错误的数字) - 代码中的
#""#是Swift的多行字符串字面量,避免转义字符的繁琐处理
内容的提问来源于stack exchange,提问作者Bart
相关产品推荐
相关产品推荐

