我从 csv 文件中读取数据,并希望使用 stringWithContentsOfFile 拆分我得到的长字符串,这是一个多行字符串,其中单独的行表示 csv 文件中的行。我该怎么做呢?
问问题
21030 次
6 回答
43
以防万一有人像我一样偶然发现这个问题。这将适用于任何换行符:
NSCharacterSet *separator = [NSCharacterSet newlineCharacterSet];
NSArray *rows = [yourString componentsSeparatedByCharactersInSet:separator];
于 2015-04-09T09:38:37.073 回答
31
您可以将字符串分解为字符串数组,然后根据需要进行操作。
NSArray *brokenByLines=[yourString componentsSeparatedByString:@"\n"]
于 2013-03-01T11:25:08.813 回答
21
您应该知道,这\n
不是用于分割新行的唯一字符。例如,如果文件保存在 Windows 中,则换行符将为\r\n
. 阅读Wikipedia 中的 Newline 文章以了解更多信息。
因此,如果您只使用componentsSeparatedByString("\n")
,您可能会得到意想不到的结果。
let multiLineString = "Line 1\r\nLine 2\r\nLine 3\r\n"
let lineArray = multiLineStringRN.componentsSeparatedByString("\n")
// ["Line 1\r", "Line 2\r", "Line 3\r", ""]
注意残差\r
和空数组元素。
有几种方法可以避免这些问题。
解决方案
1.componentsSeparatedByCharactersInSet
let multiLineString = "Line 1\nLine 2\r\nLine 3\n"
let newlineChars = NSCharacterSet.newlineCharacterSet()
let lineArray = multiLineString.componentsSeparatedByCharactersInSet(newlineChars).filter{!$0.isEmpty}
// "[Line 1, Line 2, Line 3]"
如果filter
未使用,\r\n
则将产生一个空数组元素,因为它被计为两个字符,因此在同一位置将字符串分隔两次。
2.split
let multiLineString = "Line 1\nLine 2\r\nLine 3\n"
let newlineChars = NSCharacterSet.newlineCharacterSet()
let lineArray = multiLineString.utf16.split { newlineChars.characterIsMember($0) }.flatMap(String.init)
// "[Line 1, Line 2, Line 3]"
或者
let multiLineString = "Line 1\nLine 2\r\nLine 3\n"
let lineArray = multiLineString.characters.split { $0 == "\n" || $0 == "\r\n" }.map(String.init)
// "[Line 1, Line 2, Line 3]"
这里\r\n
被算作一个 Swift 字符(一个扩展的字形簇)
3.enumerateLines
let multiLineString = "Line 1\nLine 2\r\nLine 3\n"
var lineArray = [String]()
multiLineString.enumerateLines { (line, stop) -> () in
lineArray.append(line)
}
// "[Line 1, Line 2, Line 3]"
有关enumerateLine
语法的更多信息,请参阅此答案。
笔记:
- 多行字符串通常不会混合两者
\r\n
,\n
但我在这里这样做是为了表明这些方法可以处理这两种格式。 NSCharacterSet.newlineCharacterSet()
是定义为 (U+000A–U+000D, U+0085) 的换行符,其中包括\r
和\n
。- 这个答案是对我上一个问题的答案的总结。阅读这些答案以获取更多详细信息。
于 2015-08-18T03:16:54.277 回答
13
斯威夫特 3版本:
let lines = yourString.components(separatedBy: .newlines)
又好又短。
于 2017-02-21T06:19:22.857 回答
2
您需要用“\n”分隔您的内容。
NSString *str= [NSString stringWithContentsOfFile:filePathLib encoding:NSUTF8StringEncoding error:nil];
NSArray *rows = [str componentsSeparatedByString:@"\n"];
for(int i =0;i<[rows count];i++)
NSLog(@"Row %d: %@",i,[rows objectAtIndex:i]);
于 2013-03-01T11:42:58.107 回答
1
这是我的看法:
NSString* string = @"FOO\r\nBAR\r\r\n\rATZ\rELM327 v1.5";
NSCharacterSet* newlineSet = [NSCharacterSet newlineCharacterSet];
NSCharacterSet* whitespaceSet = [NSCharacterSet whitespaceAndNewlineCharacterSet];
NSArray<NSString*>* components = [string componentsSeparatedByCharactersInSet:newlineSet];
NSPredicate* predicate = [NSPredicate predicateWithBlock:^BOOL(NSString* _Nullable string, NSDictionary<NSString *,id> * _Nullable bindings){
return [string stringByTrimmingCharactersInSet:whitespaceSet].length > 0;
}];
NSArray<NSString*>* lines = [components filteredArrayUsingPredicate:predicate];
[lines enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSLog( @"Line %u = '%@'", idx, obj );
}];
运行此打印:
2017-10-24 15:26:05.380 Untitled 5[64977:3182818] Line 0 = 'FOO'
2017-10-24 15:26:05.380 Untitled 5[64977:3182818] Line 1 = 'BAR'
2017-10-24 15:26:05.380 Untitled 5[64977:3182818] Line 2 = 'ATZ'
2017-10-24 15:26:05.380 Untitled 5[64977:3182818] Line 3 = 'ELM327 v1.5'
它可能不是最有效的方法(可能使用 anNSScanner
会更快),但它解决了这里的问题。
于 2017-10-24T15:03:50.163 回答