【问题标题】:Swift format invalid URLs to valid onesSwift 将无效 URL 格式化为有效 URL
【发布时间】:2021-01-14 15:47:37
【问题描述】:

我想将 invalid URLs 折射为 valid如果可能,否则只返回一个空的 String

这里有 5 个例子:

请以你的名字呼唤我 https://www.amazon.de/dp/B07B58SGWP/ref=cm_sw_r_cp_api_fabc_iCJ6Fb0QVVW8Y?_encoding=UTF8&psc=1

https://farfetch.onelink.me/yQyB/b9f5e5d2?af_dp=https%3A%2F%2Fwww.farfetch.com%2Fshopping%2Fitem-16119737.aspx&af_web_dp=https%3A%2F%2Fwww.farfetch.com%2Fitem-16119737.aspx Shoppen Golden Goose 'Hi Star' 运动鞋

Schau dir LANDSKRONA von IKEA an。 Hier noch weitere 信息: https://ingka.page.link/gqV9dAw61TqNJrne9

https://www.amazon.de/DALLE-PIANE-CASHMERE-Anthrazit-Einheitsgröße/dp/B06XY2ZGBZ/ref=mp_s_a_1_13_sspa?dchild=1&keywords=dalle%2Bpiane%2Bcashmere%2Bschal&qid=1610091194&sprefix=dalle%2Bpia&sr=8-13-spons&psc=1&spLa=ZW5jcnlwdGVkUXVhbGlmaWVyPUExT0hHOFRLWElYVUJBJmVuY3J5cHRlZElkPUEwOTY1ODUyOUJWWUU4MlY0SVUwJmVuY3J5cHRlZEFkSWQ9QTA0ODk2NzEzSDZNSUJOR1haREVTJndpZGdldE5hbWU9c3BfcGhvbmVfc2VhcmNoX210ZiZhY3Rpb249Y2xpY2tSZWRpcmVjdCZkb05vdExvZ0NsaWNrPXRydWU&th=1

https://www.apple.com/de/shop/buy-ipad/ipad-air/64gb-grün-wifi

所以我对此进行了讨论,我需要一个函数,将String 剥离为实际的URL(仅前三个示例),但还要折射那些不能在有效@987654330 中的字母@。我主要在第二个中挣扎。我不太明白为什么这些不能在valid Swift URL 中重新生成,即使它们可以在普通的网络浏览器中打开......

感谢任何帮助!

【问题讨论】:

  • 克里斯,你不应该这样做!在任何情况下,首先,避免在支持或任何主要来源中创建无效的 URL 字符串(例如,手动将 URL 字符串键入表单中的文本输入字段等的人。 )。客户端的任何“修复”都只能是一个脆弱的创可贴,它可能在今天起作用,但在一周后就不行了。因此,在客户端,您应该净获取语法上无效的 URL。
  • 我知道,我现在正在避免它。但是我的数据库中已经有一些错误的 url,我需要更改它们。数量不多,大概50-100个吧。但我需要改变它们。
  • 而且,现在所有这 5 个示例在我的应用程序中都无效,因此用户会收到一些错误消息提示。但这并不是我想要的,因为示例中实际上存在有效的 URL,我只需要提取它们。我希望我在这里有道理@CouchDeveloper:D
  • 前 3 个是:let candidateURL = thatString.components(separator: .whiteSpacesAndNewLines).first(where: { URL($0) != nil }),但未针对编译器进行测试。
  • 如果这个数据库在后端,那么,打印出所有无效的 URL。手动提取错误的路径组件,然后使用工具应用适当的百分比编码。如果金额小于 20 或 100,您可能会在尝试使用脚本解决之前完成。

标签: ios swift string url


【解决方案1】:

一个可能的解决方案是尝试查找一个 URL。 让我们分离每个“子元素”,然后测试每个子元素,并尝试百分比转义无效字符。

func findingPossibleURL(in string: String) -> URL? {
    let components = string.components(separatedBy: .whitespacesAndNewlines)
    let possibleURLs = components.compactMap { aCandidate -> URL? in
        if let range = aCandidate.range(of: "http") {
            let candidate = String(aCandidate[range.lowerBound...])
            if let asSuch = URL(string: candidate) {
                return asSuch
            } else {
                if let percentEscaped = candidate.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) {
                    return URL(string: percentEscaped)
                }
            }
        }
        return nil
    }
    return possibleURLs.first
}

使用示例:

let stringToTest = ...
if let url = URL(string: stringToTest) {
    //That's the URL
} else if let url = findingPossibleURL(in: stringToTest) {
    //That's the URL
} else {
    //We couldn't find a URL
}

测试:

let tests = ["Call me by your name https://www.amazon.de/dp/B07B58SGWP/ref=cm_sw_r_cp_api_fabc_iCJ6Fb0QVVW8Y?_encoding=UTF8&psc=1",
             "https://farfetch.onelink.me/yQyB/b9f5e5d2?af_dp=https%3A%2F%2Fwww.farfetch.com%2Fshopping%2Fitem-16119737.aspx&af_web_dp=https%3A%2F%2Fwww.farfetch.com%2Fitem-16119737.aspx Shoppen Golden Goose 'Hi Star' Sneakers",
             "Schau dir LANDSKRONA von IKEA an. Hier noch weitere Informationen: https://ingka.page.link/gqV9dAw61TqNJrne9",
             "https://www.amazon.de/DALLE-PIANE-CASHMERE-Anthrazit-Einheitsgröße/dp/B06XY2ZGBZ/ref=mp_s_a_1_13_sspa?dchild=1&keywords=dalle%2Bpiane%2Bcashmere%2Bschal&qid=1610091194&sprefix=dalle%2Bpia&sr=8-13-spons&psc=1&spLa=ZW5jcnlwdGVkUXVhbGlmaWVyPUExT0hHOFRLWElYVUJBJmVuY3J5cHRlZElkPUEwOTY1ODUyOUJWWUU4MlY0SVUwJmVuY3J5cHRlZEFkSWQ9QTA0ODk2NzEzSDZNSUJOR1haREVTJndpZGdldE5hbWU9c3BfcGhvbmVfc2VhcmNoX210ZiZhY3Rpb249Y2xpY2tSZWRpcmVjdCZkb05vdExvZ0NsaWNrPXRydWU&th=1",
             "https://www.apple.com/de/shop/buy-ipad/ipad-air/64gb-grün-wifi",
             "hello world",
             "",
             "Gerade entdechttps://www.zalando.at/adidas-originals-tight-leggings-hosen-blackwhite-ad121a0er-q11.html"]
tests.forEach { aTest in
    print("Testing: \(aTest)")

    if let url = URL(string: aTest) {
        print("Found URL: \(url)")
    } else if let url = findingPossibleURL(in: aTest) {
        print("Found URL: \(url)")
    } else {
        print("NO URL FOUND")
    }
}

【讨论】:

  • 对于前三个示例来说似乎是一个很好的解决方案!但是最后两个呢?这些实际上是有效的 URL,但是由于 exaples 的“ü”,我的 textView 失败了......关于如何折射这些的任何想法?
  • 您是否运行了测试,然后将输出复制/粘贴到您的网络浏览器中?它百分比转义它,使其成为有效的 URL 对象,但它们指向正确的网页。我不能保证它适用于所有人,但至少适用于这些人。
  • 我认为它正在工作,实际上还有一个案例丢失了。一个包含有效字符串的完整字符串,例如: "Gerade entdechttps://www.zalando.at/adidas-originals-tight-leggings-hosen-blackwhite-ad121a0er-q11.html" .
  • 再添加一个else if case 来检查String 是否包含 一个有效的URL
  • 更新答案现在应该可以解决这个问题。如果所有网址都以“http”开头。如果不是这样,那就更难了。
猜你喜欢
  • 2018-04-02
  • 2016-04-23
  • 1970-01-01
  • 1970-01-01
  • 2021-06-03
  • 1970-01-01
  • 2016-08-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多