テキストファイルから取得した文字列があります。
テキストファイル:
Line 1
Line 2
Line 3
...
1行に1つの配列要素を配列に変換したいと思います。
[ "Line 1", "Line 2", "Line 3", ... ]
ファイルの保存方法に応じて、文字列は次のいずれかの形式になります。
string = "Line 1\nLine 2\nLine 3\n..."
どこ \n
は改行(改行)文字です
string = "Line 1\r\nLine 2\r\nLine 3\r\n..."
どこ \r
は復帰文字です。
私が理解しているように、\n
は今日、Apple/Linuxで一般的に使用されていますが、\r\n
はWindowsで使用されます。
空の要素のない文字列配列を取得するには、どのように文字列を改行で分割しますか?
以下の解決策がいくつかあります。この時点では、他の選択肢よりも正しいものを1つ選択する強い理由はありません。選択に影響を与える可能性のあるいくつかの要因は、(1)それがいかに「迅速」であるか、および(2)非常に長い文字列の場合にどれほど速いかである可能性があります。それらの1つ以上を賛成するか、コメントを残してフィードバックを提供できます。
Swift 5以降
新しいString
プロパティを使用してCharacter
を分割できます isNewline
:
let sentence = "Line 1\nLine 2\nLine 3\n"
var lines = sentence.split { $0.isNewline }
print(lines) // "[Line 1, Line 2, Line 3]"
元の回答
StringメソッドenumerateLinesを使用できます。
文字列のすべての行を列挙します。
Swift 3以降
let sentence = "Line 1\nLine 2\nLine 3\n"
var lines: [String] = []
sentence.enumerateLines { line, _ in
lines.append(line)
}
print(lines) // "[Line 1, Line 2, Line 3]"
extension String {
var lines: [String] {
var result: [String] = []
enumerateLines { line, _ in result.append(line) }
return result
}
}
使用法:
let sentence2 = "Line 4\nLine 5\nLine 6\n"
let sentence2Lines = sentence2.lines
print(sentence2Lines) // ["Line 4", "Line 5", "Line 6"]
let sentence3 = "Line 7\r\nLine 8\r\nLine 9\r\n"
let sentence3Lines = sentence3.lines
print(sentence3Lines) // "[Line 7, Line 8, Line 9]"
Xcode 8.2、Swift 3.0.1:
NSStringメソッドを使用components(separatedBy:)
let text = "line1\nline2"
let array = text.components(separatedBy: CharacterSet.newlines)
または、Leo Dabus
の回答のように、StringメソッドenumerateLinesを使用します
Swift 2では、トップレベルのsplit
関数がCollectionType
のメソッドになりました(これは、String
sの「文字ビュー」のそれぞれが準拠します) to)メソッドには2つのバージョンがあり、特定の要素をセパレーターとして扱う必要があるかどうかを示す述語としてクロージャーを使用するバージョンが必要です。
_string.utf16
_を使用して文字列から文字コレクションからUTF16文字のコレクションを取得し、NSCharacterSet
APIと互換性を持たせることができます。このようにして、文字列内の特定の文字が改行文字セットのメンバーであるかどうかをクロージャー内で簡単に確認できます。
split(_:)
はSubSequence
の文字(基本的にはSlice
)を返すため、通常はより有用な文字列の配列に変換し直す必要があることに注意してください。 flatMap(String.init)
を使用してこれを実行しました-String
の_UTF16View
_イニシャライザは失敗する可能性があるため、flatMap
を使用するとnil
の値は無視されますこれは返される可能性があり、オプションではない文字列の配列を確実に取得します。
だから、これを行うためのNice Swiftのような方法の場合:
_let str = "Line 1\nLine 2\r\nLine 3\n"
let newlineChars = NSCharacterSet.newlineCharacterSet()
let lines = str.utf16.split { newlineChars.characterIsMember($0) }.flatMap(String.init)
// lines = ["Line 1", "Line 2", "Line 3"]
_
これがすばらしいのは、split
メソッドにパラメータallowEmptySubsequences
があり、結果に空の文字シーケンスが含まれないようにすることです。これはデフォルトでfalse
なので、実際に指定する必要はありません。
NSCharacterSet
を完全に避けたい場合は、Unicode準拠のCharacter
sのコレクションを簡単に分割できます。
_let lines = str.characters.split { $0 == "\n" || $0 == "\r\n" }.map(String.init)
_
Swiftは_"\r\n"
_を単一の拡張書記素クラスターとして扱い、Character
を作成する代わりにそれを単一のString
として比較に使用できます。また、Character
から文字列を作成するためのイニシャライザは失敗しないため、map
のみを使用できます。
この回答は、すでに提供されている他のソリューションの要約です。それは私の より完全な答え から来ていますが、実際の方法の選択肢をここで利用できると便利です。
新しい行は通常_\n
_文字で作成されますが、_\r\n
_(Windowsに保存されたファイルから)で作成することもできます。
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つの文字としてカウントされ、文字列を同じ場所で2回区切るため、空の配列要素が生成されます。
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
_は1つの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
_を含みます。let test1 = "Line1\n\rLine2\nLine3\rLine4"
let t1 = test1.componentsSeparatedByCharactersInSet(NSCharacterSet.newlineCharacterSet())
let t2 = t1.filter{ $0 != "" }
let t3 = t1.filter{ !$0.isEmpty }
記録として、スウィフトの財団CharacterSet
をスプリット内で使用できます。
extension String {
var lines: [String] {
return split { String($0).rangeOfCharacter(from: .newlines) != nil }.map(String.init)
}
}
extension String {
var lines: [String] {
return split { CharacterSet.newlines.contains($0.unicodeScalars.first!) }.map(String.init)
}
}
空の要素のない文字列配列を取得するには、どのように文字列を改行で分割しますか?
あなたはほとんどそこにいました-ここで異なるのは単に末尾のクロージャです:
let array = stringFromFile.componentsSeparatedByCharactersInSet(NSCharacterSet.newlineCharacterSet()).filter{!$0.isEmpty}
これは次と同じです:
let newLineChars = NSCharacterSet.newlineCharacterSet() // newline characters defined as (U+000A–U+000D, U+0085)
let array = stringFromFile.componentsSeparatedByCharactersInSet(newLineChars).filter{!$0.isEmpty}
ETA:末尾のクロージャーで不要な余分なブラケットを削除
Swift 4:
CSVをまだ保存していない場合は、最初に文字列に保存してから、不要な改行を削除して文字列を「クリーン」にすることをお勧めします
let dataString = String(data: yourData!, encoding: .utf8)!
var cleanFile = dataString.replacingOccurrences(of: "\r", with: "\n")
cleanFile = cleanFile.replacingOccurrences(of: "\n\n", with: "\n")
上記は、最も望ましい形式の文字列を提供し、セパレータとして\ nを使用して文字列を区切ることができます。
let csvStrings = cleanFile.components(separatedBy: ["\n"])
これで、次のような3つの項目の配列ができました。
["Line1"、 "Line2"、 "Line3"]
私はCSVファイルを使用していますが、これを行った後、アイテムをコンポーネントに分割しています。
["Line1、Line2、Line3"、 "LineA、LineB、LineC"]
let component0 = csvStrings[0].components(separatedBy: [","]) // ["Line1","Line2","Line3"]
let component1 = csvStrings[1].components(separatedBy: [","]) // ["LineA","LineB","LineC"]
let getName = "Davender+Verma"
let cleanFile = getName.replacingOccurrences(of: "+", with: "+\n")
self.upcomingViewPetName.text = cleanFile
Output: Davender+
verma
Or
let getName = "Davender+Verma"
let cleanFile = getName.replacingOccurrences(of: "+", with: "\n")
self.upcomingViewPetName.text = cleanFile
Output: Davender
verma