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

时间:2013-03-01 11:16:34

标签: ios nsstring newline

我从csv文件中读取,并希望使用stringWithContentsOfFile分割我得到的长字符串,这是一个多行字符串,各行代表csv文件中的行。我该怎么做?

6 个答案:

答案 0 :(得分:41)

万一有人像我一样偶然发现这个问题。这适用于任何换行符:

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

答案 1 :(得分:28)

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

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

答案 2 :(得分:15)

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

因此,如果你只使用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语法的详情,请参阅this answer

注意:

  • 多行字符串通常不会同时混合\r\n\n,但我这样做是为了表明这些方法可以处理这两种格式。
  • NSCharacterSet.newlineCharacterSet()是换行符,定义为(U + 000A-U + 000D,U + 0085),其中包括\r\n
  • 这个答案总结了my previous question的答案。阅读这些答案以获取更多细节。

答案 3 :(得分:7)

Swift 3 版本:

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

好又短。

答案 4 :(得分: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]);

答案 5 :(得分:0)

这是我的看法:

    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会更快),但它解决了这里的问题。