我正在尝试解析我遵循以下格式的字符串
Key: Object\n
Key: Object\n
Key: Object\n
进入NSDictionary,以便我更容易访问它。我的问题是:有没有更好的方法来实现这已经纳入obj-c?我的第一个想法是基于:和换行符的分离形成一个数组,然后使用偶数值作为键,奇数值作为对象,但这看起来有点过于复杂。
答案 0 :(得分:3)
NSString *str = @"Key1: Object1\nKey2: Object2\nKey3: Object3\n";
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
NSArray *lines = [str componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
for (NSString *aKeyValue in lines)
{
NSArray *components = [aKeyValue componentsSeparatedByString:@":"];
if ([components count] != 2) continue; //Bypass stranges lines, like the last one
NSString *key = [components[0] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
NSString *value = [components[1] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
[dict setObject:value forKey:key];
}
NSLog(@"Dict:\n%@", dict);
这给出了:
$> Dict:
{
Key1 = Object1;
Key2 = Object2;
Key3 = Object3;
}
注意:我必须使用不同的键重命名您的String,因为它们必须是唯一的(否则,它将替换仅保留最后一个的值)。如果不是这样,您可能不想要NSDictionary
。
答案 1 :(得分:1)
此代码应该有效(在Swift中):
func parseString(_ str: String) -> Dictionary<String, String> {
let lines = str.components(separatedBy: .newlines)
var dict = [String: String]()
for line in lines {
let list = line.components(separatedBy: ": ")
if list.count == 2 {
dict[list[0]] = list[1]
}
}
return dict
}
首先,我们创建一个带有线条的数组,然后对于每一行,我们提取由冒号分隔的键和值。
答案 2 :(得分:1)
撰写本文时提供的所有解决方案都会创建一系列行,然后处理这些行。 NSString
提供方法enumerateLinesUsingBlock:
以避免创建此中间行数组。假设您的字符串由变量str
引用,则:
NSMutableDictionary *results = [NSMutableDictionary new];
[str enumerateLinesUsingBlock:^(NSString *line, BOOL *stop)
{
NSArray<NSString *> *kvPair = [line componentsSeparatedByString:@":"]; // split key & value
if (kvPair.count != 2) return; // ignore any line not matching "key : value"
NSString *key = [kvPair[0] stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceCharacterSet]; // remove any whitespace
NSString *value = [kvPair[1] stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceCharacterSet];
results[key] = value;
}];
将在results
生成字典。
注意:传递给块的stop
参数是允许提前终止行枚举,在此示例中不使用它。但是,如果发现格式错误的行,则可以使用它来提前终止解析。
答案 3 :(得分:0)
使用Objective C没有更好的方法。这是你如何处理这个问题。用新行字符分隔字符串,然后再用&#34;:&#34;打破每个行字符串,将左边部分放在键上,右边部分放到值。
NSString *string = @"name: Jack Johnson\n\
address: Australia\n\
interest: Singing\n\";
NSString *trimmedString = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSArray *keyValuePairs = [trimmedString componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
for (NSString *keyValuePair in keyValuePairs) {
NSArray *keyValues = [keyValuePair componentsSeparatedByString:@":"];
dict[[keyValues.firstObject stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]] = [keyValues.lastObject stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
}
NSLog(@"%@", dict);
像这样的东西。但这很快就像swift一样,
let keyValueTuple = string.trimmingCharacters(in: .whitespacesAndNewlines)
.components(separatedBy: .newlines)
.map { line -> (String, String) in
let keyValuePairs = line.components(separatedBy: CharacterSet(charactersIn: ":"))
let key = keyValuePairs.first!.trimmingCharacters(in: .whitespaces)
let value = keyValuePairs.last!.trimmingCharacters(in: .whitespaces)
return (key, value)
}
let dict = Dictionary(uniqueKeysWithValues: keyValueTuple)