我正试图解析一些HTML来拉取字符串出现之后的所有链接:
市场登录链接
只使用Swift 4标准库收集项目URL的列表。
我想我需要的是一个for循环,它继续检查字符,条件是一旦找到完整的字符串,它就开始将下面的项目URL读入数组,直到达到双引号为止,然后停止并重复此过程,直到文件结束。在C语言中,我们稍微熟悉一些,我们可以访问一个函数(我认为是fgetc),该函数在推进文件的位置指示器时执行此操作。在Swift中有类似的方法吗?
到目前为止,我的代码只能在需要查找10个字符串时找到我要查找的字符串的第一个匹配项。

import Foundation

extension String {
    func slice(from: String, to: String) -> String? {
        return (range(of: from)?.upperBound).flatMap { substringFrom in
            (range(of: to, range: substringFrom..<endIndex)?.lowerBound).map { substringTo in
                String(self[substringFrom..<substringTo])
            }
        }
    }
}

let itemListURL = URL(string: "http://steamcommunity.com/market/search?appid=252490")!
let itemListHTML = try String(contentsOf: itemListURL, encoding: .utf8)
let itemURL = URL(string: itemListHTML.slice(from: "market_listing_row_link\" href=\"", to: "\"")!)!

print(itemURL)

// Prints the current first URL found matching: http://steamcommunity.com/market/listings/252490/Wyrm%20Chest

最佳答案

您可以使用regex查找两个特定字符串之间的所有字符串匹配项(请选中此选项,以便answer),并使用此answer中的扩展方法ranges(of:)来获取该regex模式的所有范围。你只需要把options.regularExpression传递给那个方法。

extension String {
    func ranges(of string: String, options: CompareOptions = .literal) -> [Range<Index>] {
        var result: [Range<Index>] = []
        var start = startIndex
        while let range = range(of: string, options: options, range: start..<endIndex) {
            result.append(range)
            start = range.lowerBound < range.upperBound ? range.upperBound : index(range.lowerBound, offsetBy: 1, limitedBy: endIndex) ?? endIndex
        }
        return result
    }
    func slices(from: String, to: String) -> [Substring] {
        let pattern = "(?<=" + from + ").*?(?=" + to + ")"
        return ranges(of: pattern, options: .regularExpression)
            .map{ self[$0] }
    }
}

试验场
let itemListURL = URL(string: "http://steamcommunity.com/market/search?appid=252490")!
let itemListHTML = try! String(contentsOf: itemListURL, encoding: .utf8)
let result = itemListHTML.slices(from: "market_listing_row_link\" href=\"", to: "\"")
result.forEach({print($0)})

结果
http://steamcommunity.com/market/listings/252490/Night%20Howler%20AK47
http://steamcommunity.com/market/listings/252490/Hellcat%20SAR
http://steamcommunity.com/market/listings/252490/Metal
http://steamcommunity.com/market/listings/252490/Volcanic%20Stone%20Hatchet
http://steamcommunity.com/market/listings/252490/Box
http://steamcommunity.com/market/listings/252490/High%20Quality%20Bag
http://steamcommunity.com/market/listings/252490/Utilizer%20Pants
http://steamcommunity.com/market/listings/252490/Lizard%20Skull
http://steamcommunity.com/market/listings/252490/Frost%20Wolf
http://steamcommunity.com/market/listings/252490/Cloth

08-17 10:55