如何从Swift iOS中的String获取安全值?

时间:2015-04-11 10:15:43

标签: ios swift

我有EKParticipant对象,描述如下:

item description: EKAttendee <0x1c0b7d90> {UUID = 116B99AB9-41AC-4741-A288-B67172298625; name = Snaggy  Snags; email = snaggy@gmail.com; status = 4; role = 1; type = 1}

如何安全地将此字符串拆分为Dictionary以便在email键值后获取?

这是我到目前为止所做的:

extension String {
    func split(splitter: String) -> Array<String> {
        let regEx = NSRegularExpression(pattern: splitter, options: NSRegularExpressionOptions(), error: nil)!
        let stop = "SomeStringThatYouDoNotExpectToOccurInSelf"
        let modifiedString = regEx.stringByReplacingMatchesInString(self, options: NSMatchingOptions(), range: NSMakeRange(0, countElements(self)), withTemplate: stop)

        return modifiedString.componentsSeparatedByString(stop)
    }

    func removeCharsFromEnd(count:Int) -> String{
        let stringLength = countElements(self)

        let substringIndex = (stringLength < count) ? 0 : stringLength - count

        return self.substringToIndex(advance(self.startIndex, substringIndex))
    }
}


var str = "item description: EKAttendee <0x1c0b7d90> {UUID = 16B99AB9-41AC-4742-A288-B67172299625; name = Snaggy  Snags; email = snaggy@gmail.com; status = 4; role = 1; type = 1}"


var newStr = str.split("\\{")[1]

newStr = newStr.removeCharsFromEnd(1)

所以现在newStr等于:

UUID = 16B99AB9-41AC-4741-A288-B67172298625; name = Snaggy  Snags; email = snaggy@gmail.com; status = 4; role = 1; type = 1

下一步是什么?

谢谢,

3 个答案:

答案 0 :(得分:1)

您可以使用componentsSeparatedByString方法提取元素,如下所示:

extension String {
    var elements:(udid: String, name: String, email: String, status: Int, role: Int, type: Int) {
        let components = componentsSeparatedByString("; ")
        if components.count == 6 {
            let udid = components[0].componentsSeparatedByString(" = ").last ?? ""
            let name = components[1].componentsSeparatedByString(" = ").last ?? ""
            let email = components[2].componentsSeparatedByString(" = ").last ?? ""
            let status = components[3].componentsSeparatedByString(" = ").last ?? ""
            let role = components[4].componentsSeparatedByString(" = ").last ?? ""
            let type = components[5].componentsSeparatedByString(" = ").last ?? ""
            return (udid, name, email, (status as NSString).integerValue, (role as NSString).integerValue, (type as NSString).integerValue)
        }
        return ("","","",0,0,0)
    }
}

let input = "UUID = 16B99AB9-41AC-4741-A288-B67172298625; name = Snaggy  Snags; email = snaggy@gmail.com; status = 4; role = 1; type = 1"

let result = input.elements   // (.0 "16B99AB9-41AC-4741-A288-B67172298625", .1 "Snaggy  Snags", .2 "snaggy@gmail.com", .3 4, .4 1, .5 1, .6 "UUID = 16B99AB9-41AC-4741-A288-B67172298625; name = Snaggy  Snags; email = snaggy@gmail.com; status = 4; role = 1; type = 1")

println(result.udid)                // "16B99AB9-41AC-4741-A288-B67172298625"
println(result.name)                // "Snaggy  Snags"
println(result.email)               // "snaggy@gmail.com"
println(result.status.description)  // "4"
println(result.role.description)    // "1"
println(result.type.description)    // "1"

你也可以使用String的方法hasPrefix来确保你从元素中获取正确的信息,即使它们按照以下方式返回无序信息:

extension String {
    var elements:(udid: String, name: String, email: String, status: Int, role: Int, type: Int) {
        let components = componentsSeparatedByString("; ")
        var udid = "", name = "", email = "", status = 0, role = 0, type = 0
        for item in components {
            println(item)
            if item.hasPrefix("UUID = "){
                udid = item.substringWithRange(Range(start: advance(item.startIndex, 7), end: item.endIndex))
            }
            if item.hasPrefix("name = "){
                name = item.substringWithRange(Range(start: advance(item.startIndex, 7), end: item.endIndex))
            }
            if item.hasPrefix("email = "){
                email = item.substringWithRange(Range(start: advance(item.startIndex, 8), end: item.endIndex))
            }
            if item.hasPrefix("status = "){
                status = (item.substringWithRange(Range(start: advance(item.startIndex, 9), end: item.endIndex)) as NSString).integerValue
            }
            if item.hasPrefix("role = "){
                role = (item.substringWithRange(Range(start: advance(item.startIndex, 7), end: item.endIndex)) as NSString).integerValue
            }
            if item.hasPrefix("type = "){
                type = (item.substringWithRange(Range(start: advance(item.startIndex, 7), end: item.endIndex)) as NSString).integerValue
            }
        }
        return (udid, name, email, status, role, type)
    }
}

let input = "UUID = 16B99AB9-41AC-4741-A288-B67172298625; name = Snaggy  Snags; email = snaggy@gmail.com; status = 4; role = 1; type = 1"
let elements = input.elements             // (.0 "16B99AB9-41AC-4741-A288-B67172298625", .1 "Snaggy  Snags", .2 "snaggy@gmail.com", .3 4, .4 1, .5 1)
let udid = elements.udid                  // "16B99AB9-41AC-4741-A288-B67172298625"
let name = elements.name                  // "Snaggy  Snags"
let email = elements.email                // "snaggy@gmail.com"
let status = elements.status.description  // "4"
let role = elements.role.description      // "1"
let type = elements.type.description      // "1"

答案 1 :(得分:0)

以下是获取电子邮件或在出现问题时返回nil的方法:

 func fetchEmailIfExists(str:String) -> String?{

    var email:String?

    for item:String in str.split(";"){

        if item.contains("email"){

            var emailPart = item.trim()

            if emailPart.componentsSeparatedByString("=").first?.trim() == "email" {
                if let temp:String = emailPart.componentsSeparatedByString("=").last?.trim(){
                    return temp
                }
            }
        }
    }

    return email
}

助手

extension String {
    func split(splitter: String) -> Array<String> {
        let regEx = NSRegularExpression(pattern: splitter, options: NSRegularExpressionOptions(), error: nil)!
        let stop = "SomeStringThatYouDoNotExpectToOccurInSelf"
        let modifiedString = regEx.stringByReplacingMatchesInString(self, options: NSMatchingOptions(), range: NSMakeRange(0, countElements(self)), withTemplate: stop)

        return modifiedString.componentsSeparatedByString(stop)
    }


    func trim() -> String {
        return self.stringByTrimmingCharactersInSet(.whitespaceAndNewlineCharacterSet())
    }

    func contains(find: String) -> Bool{
       return self.rangeOfString(find) != nil
    }
}

答案 2 :(得分:0)

这是NSScanner的完美用例。 stringToDictionary采用与您类似的字符串并返回[String: String]的字典。无论键/值对的数量如何,您都可以将其用于格式的任何字符串。但是,当值包含分号或等号时,它会崩溃。

let string = "item description: EKAttendee <0x1c0b7d90> {UUID = 116B99AB9-41AC-4741-A288-B67172298625; name = Snaggy  Snags; email = snaggy@gmail.com; status = 4; role = 1; type = 1}"

var dictionary = stringToDictionary(string)

func stringToDictionary(input: String) -> [String: String] {
    var output = [String: String]()
    let scanner = NSScanner(string: input)
    let separatingCharacters = NSCharacterSet(charactersInString: ";}")

    scanner.scanUpToString("{", intoString: nil)
    scanner.scanString("{", intoString: nil)

    var key: NSString?, value: NSString?

    while !scanner.atEnd {
        scanner.scanUpToString(" =", intoString: &key)
        scanner.scanString("= ", intoString: nil)
        scanner.scanUpToCharactersFromSet(separatingCharacters, intoString: &value)
        scanner.scanCharactersFromSet(separatingCharacters, intoString: nil)

        if let key = key as? String, value = value as? String {
            output[key] = value
        }
    }

    return output
}