Ho letto da un file csv e voglio dividere la stringa lunga che ottengo usando stringWithContentsOfFile, che è una stringa multi linea, con singole righe che rappresentano le righe nel file csv. Come faccio a fare questo?come dividere una stringa con newline
risposta
È possibile suddividere la stringa in matrici di stringa e quindi manipolare come si desidera.
NSArray *brokenByLines=[yourString componentsSeparatedByString:@"\n"]
Questo fa un sacco di ipotesi su ciò che sono i separatori di riga. – uchuugaka
Se non si conoscono i separatori di riga: 'let lines = stringData.stringByReplacingOccurrencesOfString (" \ r \ n ", withString:" \ "n"). StringByReplacingOccurrencesOfString ("\ r", withString: "\ n") .componentsSeparatedByString ("\ n") ' – Zaphod
Uno non deve sostituire @" \ r ", se la stringa è separata con newLineCharacterSet; –
È necessario separare il contenuto con "\ 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]);
Questo fa anche supposizioni sui separatori di riga. – uchuugaka
Nel caso in cui qualcuno si imbattesse in questa domanda come ho fatto io. Questo funziona con qualsiasi caratteri di nuova riga:
NSCharacterSet *separator = [NSCharacterSet newlineCharacterSet];
NSArray *rows = [yourString componentsSeparatedByCharactersInSet:separator];
si deve essere consapevoli che \n
non è l'unico carattere utilizzato per dividere una nuova linea. Ad esempio, se il file è stato salvato in Windows, i caratteri di nuova riga saranno \r\n
. Leggi the Newline article in Wikipedia per ulteriori informazioni a riguardo.
Pertanto, se si utilizza solo componentsSeparatedByString("\n")
, è possibile ottenere risultati imprevisti.
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", ""]
nota sia il residuo \r
e l'elemento array vuoto.
Esistono diversi modi per evitare questi problemi.
Solutions
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]"
Se filter
non sono stati utilizzati, quindi \r\n
produrrebbe un elemento array vuoto perché viene contato come due caratteri, così separa la stringa due volte al stessa posizione
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]"
o
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]"
Qui \r\n
ottiene contato come un singolo carattere Swift (un cluster grafema esteso)
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]"
Per ulteriori informazioni sulla sintassi enumerateLine
, vedere anche this answer.
Note:
- una spezzata a più non sarebbe solito mescolare sia
\r\n
e\n
ma sto facendo questo qui per dimostrare che questi metodi in grado di gestire entrambi i formati. NSCharacterSet.newlineCharacterSet()
sono caratteri di nuova riga definiti come (U + 000A-U + 000D, U + 0085), che includono\r
e\n
.- Questa risposta è un riepilogo delle risposte a my previous question. Leggi quelle risposte per maggiori dettagli.
Swift 3 versione:
let lines = yourString.components(separatedBy: .newlines)
Nizza e breve.
Ecco il mio prendere su di esso:
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);
}];
Esecuzione Questo stampa:
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'
Esso non può essere il modo più efficiente (probabilmente utilizzando un NSScanner
sarebbe più veloce), ma risolve il problema qui.
Perché caricare l'intero file in memoria? Questo non aiuterà la tua impronta di memoria ... – trojanfoe
Forse è noto che il file non sarà così grande. È * solo * testo ... – uchuugaka
sì ... il file è abbastanza piccolo ... ha solo 54 righe e 4 colonne! –