Ios 字符串到字典(从QRCode字符串获取值)

Ios 字符串到字典(从QRCode字符串获取值),ios,swift,Ios,Swift,我正在尝试生成QRCode,然后读入它。我的问题是我不知道如何从QRCode字符串中获取值 我的QRCode中的字符串如下:[“firstName”:“John”,“lastName”:“Bush”] 我是这样做到的: let dict = ["firstName":firstName, "lastName": lastName] dict.description 现在我想从中获取值,我应该怎么做?我试图将字符串转换回dictionary,但无法完成。如果您真的对解析此结果感兴趣,当然有办法。

我正在尝试生成QRCode,然后读入它。我的问题是我不知道如何从QRCode字符串中获取值

我的QRCode中的字符串如下:
[“firstName”:“John”,“lastName”:“Bush”]

我是这样做到的:

let dict = ["firstName":firstName, "lastName": lastName]
dict.description

现在我想从中获取值,我应该怎么做?我试图将字符串转换回dictionary,但无法完成。

如果您真的对解析此结果感兴趣,当然有办法。它永远不会持续成功,除非有一个一致的格式来自您的来源。如果是一致的,您当然可以这样做:

//get the string representation of our dictionary
let code = "[\"firstName\": \"firstName\", \"lastName\": \"lastName\"]"
//remove the brackets
let bracketless = String(code.characters.dropFirst().dropLast())
//get rid of our quotes
let quoteless = bracketless.replacingOccurrences(of: "\"", with: "")
//split our dictionary by key/value pairs
let pairs = quoteless.components(separatedBy: ", ")
//now split our key/value pairs into each key and value component respectively
let values: [[String]] = pairs.map { $0.components(separatedBy: ": ") }

//create ourself a dictionary to populate with our parsed data
var dict: [String:Any] = [:]
values.forEach { dict[$0[0]] = $0[1] } //populate the dictionary
print(dict) // ["lastName": "lastName", "firstName": "firstName"]
func dictionary() {
   expect("[")
   if !read("]") {
      repeat {
          pair()
      } while read(",")
   }
   expect("]")
}

func pair() {
    quotedString()
    expect(":")
    quotedString()
}

func quotedString() {
   expect("\"")
   readUpTo("\"")
   expect("\"")
}
let scanner = Scanner(string: string)

func dictionary() -> [String: String]? {
    guard scanner.scanString("[", into: nil) else { return nil }

    var result: [String: String] = [:]

    if !scanner.scanString("]", into: nil) {
        repeat {
            guard let (key, value) = pair() else { return nil }
            result[key] = value
        } while scanner.scanString(",", into: nil)
    }

    guard scanner.scanString("]", into: nil) else { return nil }

    return result
}

func pair() -> (String, String)? {
    guard let key = quotedString(),
        scanner.scanString(":", into: nil),
        let value = quotedString()
    else {
            return nil
    }

    return (key, value)
}

func quotedString() -> String? {
    guard scanner.scanString("\"", into: nil) else { return nil }

    var result: NSString? = nil
    guard scanner.scanUpTo("\"", into: &result), let string = result as? String else { return nil }

    guard scanner.scanString("\"", into: nil) else { return nil }

    return string
}

最好使用标准格式(如JSON)。也许在你的情况下,这不是一个选择。我仍然想知道为什么会出现这种情况。

如果你真的对解析这个结果感兴趣,当然有办法。它永远不会持续成功,除非有一个一致的格式来自您的来源。如果是一致的,您当然可以这样做:

//get the string representation of our dictionary
let code = "[\"firstName\": \"firstName\", \"lastName\": \"lastName\"]"
//remove the brackets
let bracketless = String(code.characters.dropFirst().dropLast())
//get rid of our quotes
let quoteless = bracketless.replacingOccurrences(of: "\"", with: "")
//split our dictionary by key/value pairs
let pairs = quoteless.components(separatedBy: ", ")
//now split our key/value pairs into each key and value component respectively
let values: [[String]] = pairs.map { $0.components(separatedBy: ": ") }

//create ourself a dictionary to populate with our parsed data
var dict: [String:Any] = [:]
values.forEach { dict[$0[0]] = $0[1] } //populate the dictionary
print(dict) // ["lastName": "lastName", "firstName": "firstName"]
func dictionary() {
   expect("[")
   if !read("]") {
      repeat {
          pair()
      } while read(",")
   }
   expect("]")
}

func pair() {
    quotedString()
    expect(":")
    quotedString()
}

func quotedString() {
   expect("\"")
   readUpTo("\"")
   expect("\"")
}
let scanner = Scanner(string: string)

func dictionary() -> [String: String]? {
    guard scanner.scanString("[", into: nil) else { return nil }

    var result: [String: String] = [:]

    if !scanner.scanString("]", into: nil) {
        repeat {
            guard let (key, value) = pair() else { return nil }
            result[key] = value
        } while scanner.scanString(",", into: nil)
    }

    guard scanner.scanString("]", into: nil) else { return nil }

    return result
}

func pair() -> (String, String)? {
    guard let key = quotedString(),
        scanner.scanString(":", into: nil),
        let value = quotedString()
    else {
            return nil
    }

    return (key, value)
}

func quotedString() -> String? {
    guard scanner.scanString("\"", into: nil) else { return nil }

    var result: NSString? = nil
    guard scanner.scanUpTo("\"", into: &result), let string = result as? String else { return nil }

    guard scanner.scanString("\"", into: nil) else { return nil }

    return string
}

最好使用标准格式(如JSON)。也许在你的情况下,这不是一个选择。我仍然想知道为什么您会处于上述情况。

这是一个相当棘手的问题,来自
说明的结果实际上并不打算用作交换格式。最好的办法是使用不同的格式生成二维码。但是让我们假设现在已经太迟了

要获取数据,您需要编写一个解析器,因为系统没有为描述格式提供解析器。听起来很难,但事实并非如此。您可能会考虑使用String方法<代码>组件(分隔为:)/Cuth>,但这将变得非常低效。基金会<代码>扫描器类是一个更好的工具。

编写最简单的解析器是“递归下降”解析器。这意味着您要为每个要识别的零件编写一个函数,该函数为子零件调用此类函数。让我们看看这里有什么:

  • 最外层是字典。首先是字符串“[”,然后是由“,”分隔的键/值对,最后是另一个“]”。(也可能有空字典的情况,它只是“[]”
  • 然后我们有一对。这是一个带引号的字符串,后跟“:”和另一个带引号的字符串
  • 最后一部分是带引号的字符串。这里有引号
    ,以及下一个引号之前的任何其他字符
因此,在伪代码中,这看起来像这样:

//get the string representation of our dictionary
let code = "[\"firstName\": \"firstName\", \"lastName\": \"lastName\"]"
//remove the brackets
let bracketless = String(code.characters.dropFirst().dropLast())
//get rid of our quotes
let quoteless = bracketless.replacingOccurrences(of: "\"", with: "")
//split our dictionary by key/value pairs
let pairs = quoteless.components(separatedBy: ", ")
//now split our key/value pairs into each key and value component respectively
let values: [[String]] = pairs.map { $0.components(separatedBy: ": ") }

//create ourself a dictionary to populate with our parsed data
var dict: [String:Any] = [:]
values.forEach { dict[$0[0]] = $0[1] } //populate the dictionary
print(dict) // ["lastName": "lastName", "firstName": "firstName"]
func dictionary() {
   expect("[")
   if !read("]") {
      repeat {
          pair()
      } while read(",")
   }
   expect("]")
}

func pair() {
    quotedString()
    expect(":")
    quotedString()
}

func quotedString() {
   expect("\"")
   readUpTo("\"")
   expect("\"")
}
let scanner = Scanner(string: string)

func dictionary() -> [String: String]? {
    guard scanner.scanString("[", into: nil) else { return nil }

    var result: [String: String] = [:]

    if !scanner.scanString("]", into: nil) {
        repeat {
            guard let (key, value) = pair() else { return nil }
            result[key] = value
        } while scanner.scanString(",", into: nil)
    }

    guard scanner.scanString("]", into: nil) else { return nil }

    return result
}

func pair() -> (String, String)? {
    guard let key = quotedString(),
        scanner.scanString(":", into: nil),
        let value = quotedString()
    else {
            return nil
    }

    return (key, value)
}

func quotedString() -> String? {
    guard scanner.scanString("\"", into: nil) else { return nil }

    var result: NSString? = nil
    guard scanner.scanUpTo("\"", into: &result), let string = result as? String else { return nil }

    guard scanner.scanString("\"", into: nil) else { return nil }

    return string
}
这里,
expect
read
readUpTo
是Scanner类提供的方法的占位符。如果我们提供这些占位符,这基本上就是完整的解析器。但是像这样,它不是很有用,因为它只是忽略了数据。因此我们需要扩展解析器,使其实际返回找到的数据

最终结果可能如下所示:

//get the string representation of our dictionary
let code = "[\"firstName\": \"firstName\", \"lastName\": \"lastName\"]"
//remove the brackets
let bracketless = String(code.characters.dropFirst().dropLast())
//get rid of our quotes
let quoteless = bracketless.replacingOccurrences(of: "\"", with: "")
//split our dictionary by key/value pairs
let pairs = quoteless.components(separatedBy: ", ")
//now split our key/value pairs into each key and value component respectively
let values: [[String]] = pairs.map { $0.components(separatedBy: ": ") }

//create ourself a dictionary to populate with our parsed data
var dict: [String:Any] = [:]
values.forEach { dict[$0[0]] = $0[1] } //populate the dictionary
print(dict) // ["lastName": "lastName", "firstName": "firstName"]
func dictionary() {
   expect("[")
   if !read("]") {
      repeat {
          pair()
      } while read(",")
   }
   expect("]")
}

func pair() {
    quotedString()
    expect(":")
    quotedString()
}

func quotedString() {
   expect("\"")
   readUpTo("\"")
   expect("\"")
}
let scanner = Scanner(string: string)

func dictionary() -> [String: String]? {
    guard scanner.scanString("[", into: nil) else { return nil }

    var result: [String: String] = [:]

    if !scanner.scanString("]", into: nil) {
        repeat {
            guard let (key, value) = pair() else { return nil }
            result[key] = value
        } while scanner.scanString(",", into: nil)
    }

    guard scanner.scanString("]", into: nil) else { return nil }

    return result
}

func pair() -> (String, String)? {
    guard let key = quotedString(),
        scanner.scanString(":", into: nil),
        let value = quotedString()
    else {
            return nil
    }

    return (key, value)
}

func quotedString() -> String? {
    guard scanner.scanString("\"", into: nil) else { return nil }

    var result: NSString? = nil
    guard scanner.scanUpTo("\"", into: &result), let string = result as? String else { return nil }

    guard scanner.scanString("\"", into: nil) else { return nil }

    return string
}
代码比使用字符串拆分的黑客解决方案多一点,但也不是很复杂,而且更灵活。在这里,如果字符串本身包含“,”或“:,则不会有任何问题:“。性能也会更好,因为在这里我们只查看每个字符一次。其他解决方案必须查看每个字符三次


但它仍然存在一个问题:如果任何字符串包含双引号字符,则此解析器将失败。字典的description属性将以反斜杠引号形式输出此字符,如
\“
-这将必须在
quotedString

中处理,这是相当棘手的,来自
说明的结果实际上并不打算用作交换格式。最好使用不同的格式来生成二维码。但我们假设现在已经太晚了

为了获得数据,你需要编写一个解析器,因为系统没有提供一个描述格式。听起来很难,但实际上不是。你可以考虑使用String方法<代码>组件(分开:),但这将是非常低效的。基础<代码>扫描器< /代码>类是一个更好的工具。

要编写的最简单的解析器是“递归下降”解析器。这意味着对于要识别的每个部分,您都要编写一个函数来调用子部分的函数。因此,让我们看看这里有什么:

  • 最外层是字典。它从字符串“[”开始,然后是由“,”分隔的键/值对,最后是另一个“]”(也可能是空字典,它只是“[]”
  • 然后我们有一对。这是一个带引号的字符串,后跟“:”和另一个带引号的字符串
  • 最后一部分是带引号的字符串。这里有引号
    ,以及下一个引号之前的任何其他字符
因此,在伪代码中,这看起来像这样:

//get the string representation of our dictionary
let code = "[\"firstName\": \"firstName\", \"lastName\": \"lastName\"]"
//remove the brackets
let bracketless = String(code.characters.dropFirst().dropLast())
//get rid of our quotes
let quoteless = bracketless.replacingOccurrences(of: "\"", with: "")
//split our dictionary by key/value pairs
let pairs = quoteless.components(separatedBy: ", ")
//now split our key/value pairs into each key and value component respectively
let values: [[String]] = pairs.map { $0.components(separatedBy: ": ") }

//create ourself a dictionary to populate with our parsed data
var dict: [String:Any] = [:]
values.forEach { dict[$0[0]] = $0[1] } //populate the dictionary
print(dict) // ["lastName": "lastName", "firstName": "firstName"]
func dictionary() {
   expect("[")
   if !read("]") {
      repeat {
          pair()
      } while read(",")
   }
   expect("]")
}

func pair() {
    quotedString()
    expect(":")
    quotedString()
}

func quotedString() {
   expect("\"")
   readUpTo("\"")
   expect("\"")
}
let scanner = Scanner(string: string)

func dictionary() -> [String: String]? {
    guard scanner.scanString("[", into: nil) else { return nil }

    var result: [String: String] = [:]

    if !scanner.scanString("]", into: nil) {
        repeat {
            guard let (key, value) = pair() else { return nil }
            result[key] = value
        } while scanner.scanString(",", into: nil)
    }

    guard scanner.scanString("]", into: nil) else { return nil }

    return result
}

func pair() -> (String, String)? {
    guard let key = quotedString(),
        scanner.scanString(":", into: nil),
        let value = quotedString()
    else {
            return nil
    }

    return (key, value)
}

func quotedString() -> String? {
    guard scanner.scanString("\"", into: nil) else { return nil }

    var result: NSString? = nil
    guard scanner.scanUpTo("\"", into: &result), let string = result as? String else { return nil }

    guard scanner.scanString("\"", into: nil) else { return nil }

    return string
}
这里,
expect
read
readUpTo
是Scanner类提供的方法的占位符。如果我们提供这些占位符,这基本上就是完整的解析器。但是像这样,它不是很有用,因为它只是忽略了数据。因此我们需要扩展解析器,使其实际返回找到的数据

最终结果可能如下所示:

//get the string representation of our dictionary
let code = "[\"firstName\": \"firstName\", \"lastName\": \"lastName\"]"
//remove the brackets
let bracketless = String(code.characters.dropFirst().dropLast())
//get rid of our quotes
let quoteless = bracketless.replacingOccurrences(of: "\"", with: "")
//split our dictionary by key/value pairs
let pairs = quoteless.components(separatedBy: ", ")
//now split our key/value pairs into each key and value component respectively
let values: [[String]] = pairs.map { $0.components(separatedBy: ": ") }

//create ourself a dictionary to populate with our parsed data
var dict: [String:Any] = [:]
values.forEach { dict[$0[0]] = $0[1] } //populate the dictionary
print(dict) // ["lastName": "lastName", "firstName": "firstName"]
func dictionary() {
   expect("[")
   if !read("]") {
      repeat {
          pair()
      } while read(",")
   }
   expect("]")
}

func pair() {
    quotedString()
    expect(":")
    quotedString()
}

func quotedString() {
   expect("\"")
   readUpTo("\"")
   expect("\"")
}
let scanner = Scanner(string: string)

func dictionary() -> [String: String]? {
    guard scanner.scanString("[", into: nil) else { return nil }

    var result: [String: String] = [:]

    if !scanner.scanString("]", into: nil) {
        repeat {
            guard let (key, value) = pair() else { return nil }
            result[key] = value
        } while scanner.scanString(",", into: nil)
    }

    guard scanner.scanString("]", into: nil) else { return nil }

    return result
}

func pair() -> (String, String)? {
    guard let key = quotedString(),
        scanner.scanString(":", into: nil),
        let value = quotedString()
    else {
            return nil
    }

    return (key, value)
}

func quotedString() -> String? {
    guard scanner.scanString("\"", into: nil) else { return nil }

    var result: NSString? = nil
    guard scanner.scanUpTo("\"", into: &result), let string = result as? String else { return nil }

    guard scanner.scanString("\"", into: nil) else { return nil }

    return string
}
代码比使用字符串拆分的黑客解决方案多一点,但也不是很复杂,而且更灵活。在这里,如果字符串本身包含“,”或“:,则不会有任何问题:“。性能也会更好,因为在这里我们只查看每个字符一次。其他解决方案必须查看每个字符三次

但是它仍然有一个问题:如果您的任何字符串包含双引号字符,那么这个解析器将失败。T