如何用换行符分割string

我从一个csv文件读取,并希望拆分我得到使用stringWithContentsOfFile,这是一个多行string,每行表示CSV文件中的行的长string。 我该怎么做呢?

您可以将string分解为string数组,然后根据需要进行操作。

NSArray *brokenByLines=[yourString componentsSeparatedByString:@"\n"] 

以防万一有人像我一样绊倒这个问题。 这将适用于任何换行符:

 NSCharacterSet *separator = [NSCharacterSet newlineCharacterSet]; NSArray *rows = [yourString componentsSeparatedByCharactersInSet:separator]; 

您应该知道, \n不是用来分割新行的唯一字符。 例如,如果文件保存在Windows中,则换行符将是\r\n 。 阅读维基百科的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和空数组元素。

有几种方法可以避免这些问题。

解决scheme

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将产生一个空的数组元素,因为它被计算为两个字符,因此在相同的位置将string分隔两次。

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语法的更多信息,请参阅此答案 。

笔记:

  • 多行string通常不会混合\r\n\n但是我在这里做这个来表明这些方法可以处理这两种格式。
  • NSCharacterSet.newlineCharacterSet()是换行符,定义为(U + 000A-U + 000D,U + 0085),其中包括\r\n
  • 这个答案是对我以前的问题的答案的总结。 阅读这些答案的更多细节。

Swift 3版本:

 let lines = yourString.components(separatedBy: .newlines) 

很好,很短。

您需要将您的内容与“\ 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]); 

这是我的承诺:

  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' 

这可能不是最有效的方法(可能使用NSScanner会更快),但是它解决了这个问题。