Ios 如何使用换行符拆分字符串

Ios 如何使用换行符拆分字符串,ios,nsstring,newline,Ios,Nsstring,Newline,我从一个csv文件中读取,并希望拆分使用stringWithContentsOfFile(一个多行字符串)获得的长字符串,其中各行表示csv文件中的行。如何执行此操作?您可以将字符串拆分为字符串数组,然后根据需要进行操作 NSArray *brokenByLines=[yourString componentsSeparatedByString:@"\n"] 您需要用“\n”分隔您的内容 NSString*str=[NSString stringWithContentsOfFile:fileP

我从一个csv文件中读取,并希望拆分使用stringWithContentsOfFile(一个多行字符串)获得的长字符串,其中各行表示csv文件中的行。如何执行此操作?

您可以将字符串拆分为字符串数组,然后根据需要进行操作

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

您需要用“\n”分隔您的内容

NSString*str=[NSString stringWithContentsOfFile:filePathLib编码:NSUTF8StringEncoding错误:nil];
NSArray*行=[str组件由字符串分隔:@“\n”];

for(int i=0;i以防有人像我一样偶然发现这个问题。这将适用于任何换行符:

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

您应该知道,
\n
不是用于拆分新行的唯一字符。例如,如果文件保存在Windows中,则换行字符将是
\r\n
。有关此操作的详细信息,请阅读

因此,如果只使用由字符串(“\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.
由字符分隔的组件集合

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]"
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"
var lineArray = [String]()
multiLineString.enumerateLines { (line, stop) -> () in
    lineArray.append(line)
}
// "[Line 1, Line 2, Line 3]"
如果未使用
filter
,则
\r\n
将生成一个空数组元素,因为它被计为两个字符,因此在同一位置将字符串分隔两次

2.
拆分

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]"
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"
var lineArray = [String]()
multiLineString.enumerateLines { (line, stop) -> () in
    lineArray.append(line)
}
// "[Line 1, Line 2, Line 3]"

此处
\r\n
被计算为单个Swift字符(扩展的grapheme群集)

3.
枚举行

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]"
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"
var lineArray = [String]()
multiLineString.enumerateLines { (line, stop) -> () in
    lineArray.append(line)
}
// "[Line 1, Line 2, Line 3]"
有关
枚举行
语法的更多信息,请参见

笔记:
  • 多行字符串通常不会同时混合
    \r\n
    \n
    ,但我在这里这样做是为了说明这些方法可以处理这两种格式
  • 换行符定义为(U+000A–U+000D,U+0085),包括
    \r
    \n
  • 此答案是的答案摘要。请阅读这些答案以了解更多详细信息

Swift 3版本:

let lines = yourString.components(separatedBy: .newlines)
又好又短。

以下是我的看法:

    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 );
    }];

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

为什么要将整个文件加载到内存中?这对您的内存占用没有任何帮助…也许我们知道文件不会那么大。它只是文本…是的…文件足够小…它只有54行和4列!这对行分隔符是什么做了很多假设。如果您不知道行分隔符为:
let lines=stringData.stringByReplacingOccurrencesOfString(“\r\n”,带字符串:“\”n”)。stringByReplacingOccurrencesOfString(“\r”,带字符串:“\n”)。由字符串(“\n”)分隔的组件
不必替换@”\r,如果字符串用newLineCharacterSet分隔;这也会对行分隔符进行假设。如果行分隔符是
\r\n
(两个字符),则会在数组中生成空字符串,就像在Windows格式的文件中一样。