文字列をSwiftで配列に分割しますか?


686

ここに文字列があるとしましょう:

var fullName: String = "First Last"

文字列ベースを空白で分割し、それぞれの変数に値を割り当てたい

var fullNameArr = // something like: fullName.explode(" ") 

var firstName: String = fullNameArr[0]
var lastName: String? = fullnameArr[1]

また、ユーザーが姓を持たない場合もあります。


13
こんにちは、チェックするMacがありません。ただし、 'fullName.componentsSeparatedByString(string: "")'を試すことはできます。コピーと貼り付けを行わずに、autocomplete関数を使用して、適切な関数を取得してください。
DavidGölzhäuser2014

あなたが使用して1つの文字だけ分割、ある場合fullName.utf8.split( <utf-8 character code> )だけでなく、作品を(置き換える.utf8.utf16UTF-16の場合)。たとえば、分割+は次のようにして行うことができますfullName.utf8.split(43)
Jojodmo

また、「Daphne du Maurier」や「Charles de Lint」のように、姓にスペースが含まれる場合があります
Berry

回答:


784

Swiftの方法はsplit、次のようにグローバル関数を使用することです。

var fullName = "First Last"
var fullNameArr = split(fullName) {$0 == " "}
var firstName: String = fullNameArr[0]
var lastName: String? = fullNameArr.count > 1 ? fullNameArr[1] : nil

スウィフト2

Swift 2では、内部のCharacterViewタイプの導入により、分割の使用が少し複雑になっています。つまり、StringはSequenceTypeまたはCollectionTypeプロトコルを採用しなくなったため、代わりに.charactersプロパティを使用して、StringインスタンスのCharacterViewタイプの表現にアクセスする必要があります。(注:CharacterViewはSequenceTypeおよびCollectionTypeプロトコルを採用しています)。

let fullName = "First Last"
let fullNameArr = fullName.characters.split{$0 == " "}.map(String.init)
// or simply:
// let fullNameArr = fullName.characters.split{" "}.map(String.init)

fullNameArr[0] // First
fullNameArr[1] // Last 

98
私のテストでは、特に多くの部分に分割する必要がある文字列を扱う場合、componentsSeparatedByStringは通常かなり高速です。しかし、OPによってリストされた例では、どちらでも十分です。
Casey Perkins

9
Xcode 6.2b3以降では、splitをとして使用できますsplit("a:b::c:", {$0 == ":"}, maxSplit: Int.max, allowEmptySlices: false)
Pascal

14
componentsSeparatedByString()セパレータが単一の文字よりも長い場合でも、古い方法を使用する必要があることを覚えておいてください。言うまでもなくクールですがlet (firstName, lastName) = split(fullName) {$0 == ' '}、残念ながらうまくいきません。
NRitH 2015

3
@Kashifを使用するsplit("a,b;c,d") {$0 == "," || $0 == ";"}split("a,b;c,d") {contains(",;", $0)}
Ethan

4
Xcode 7.0の正しいコードは、fullNameArr = fullName.characters.split {$ 0 == ""} .map(String.init)にします。編集しようとしましたが、拒否されました。
skagedal 2015

1015

componentsSeparatedByStringあなたのメソッドを呼び出すだけfullName

import Foundation

var fullName: String = "First Last"
let fullNameArr = fullName.componentsSeparatedByString(" ")

var firstName: String = fullNameArr[0]
var lastName: String = fullNameArr[1]

Swift 3以降のアップデート

import Foundation

let fullName    = "First Last"
let fullNameArr = fullName.components(separatedBy: " ")

let name    = fullNameArr[0]
let surname = fullNameArr[1]

3
これは実際には基盤であることに注意してくださいNSString(Swiftはインポート時に自動的に入れ替えますFoundation)。

1
これはもはやSwift 1.2では当てはまりません。AppleはもはやSwiftの文字列を自動的にNSStringに変換しません。
elcuco

6
この回答は、Xcode 7ベータ4およびSwift 2.0で機能します。Xcodeは、NSStringに型キャストすることなく、Swift StringオブジェクトのFoundationメソッドを自動補完するようになりました。これは、Swift 1.2のXcode 6.4では当てはまりません。
Andrew

1
Foundationをインポートするまで、REPLでは機能しませんでした。
Velizar Hristov、2015

1
これ[String]はXcode 7.2で期待どおりに機能します(つまり、fullNameArrはです)。
ジョンコックス

185

これを行う最も簡単な方法は、componentsSeparatedByを使用することです。

Swift 2の場合:

import Foundation
let fullName : String = "First Last";
let fullNameArr : [String] = fullName.componentsSeparatedByString(" ")

// And then to access the individual words:

var firstName : String = fullNameArr[0]
var lastName : String = fullNameArr[1]

Swift 3の場合:

import Foundation

let fullName : String = "First Last"
let fullNameArr : [String] = fullName.components(separatedBy: " ")

// And then to access the individual words:

var firstName : String = fullNameArr[0]
var lastName : String = fullNameArr[1]

これはどこかに文書化されていますか、モーリー?単一の文字以外のもので分割する必要がある場合はどうなりますか?
NRitH 2015

10
@NRitHの検討 .componentsSeparatedByCharactersInSet(.whitespaceAndNewlineCharacterSet())
rmp251

@Crashalotそこに二つの機能は以下のとおりです。componentsSeparatedByStringcomponentsSeparatedByCharactersInSet
rmp251

130

Swift Dev。4.0(2017年5月24日)

splitSwift 4(ベータ)の新機能。

import Foundation
let sayHello = "Hello Swift 4 2017";
let result = sayHello.split(separator: " ")
print(result)

出力:

["Hello", "Swift", "4", "2017"]

値へのアクセス:

print(result[0]) // Hello
print(result[1]) // Swift
print(result[2]) // 4
print(result[3]) // 2017

Xcode 8.1 / Swift 3.0.1

これは、配列を使用した複数の区切り文字の方法です。

import Foundation
let mathString: String = "12-37*2/5"
let numbers = mathString.components(separatedBy: ["-", "*", "/"])
print(numbers)

出力:

["12", "37", "2", "5"]

8
import Foundationこれを使用しているクラスに必ず追加してください。#SavedYouFiveMinutes
Adrian

4
注意(Swift 4):のような文字列がlet a="a,,b,c"あり、使用a.split(separator: ",")すると、["a", "b", c"]デフォルトでのような配列が取得されます。これはomittingEmptySubsequences: false、デフォルトでtrue を使用して変更できます。
OderWat 2017

2
Swift 4以降で複数文字の分割はありますか?
pkamb 2018

57

Swift 4以降

個人名を適切にフォーマットする必要がある場合は、PersonNameComponentsFormatterを使用できます。

PersonNameComponentsFormatterクラスは、PersonNameComponentsオブジェクトによって表される、人の名前のコンポーネントのローカライズされた表現を提供します。このクラスを使用して、ユーザー名情報をユーザーに表示するときにローカライズされた名前を作成します。


// iOS (9.0 and later), macOS (10.11 and later), tvOS (9.0 and later), watchOS (2.0 and later)
let nameFormatter = PersonNameComponentsFormatter()

let name =  "Mr. Steven Paul Jobs Jr."
// personNameComponents requires iOS (10.0 and later)
if let nameComps  = nameFormatter.personNameComponents(from: name) {
    nameComps.namePrefix   // Mr.
    nameComps.givenName    // Steven
    nameComps.middleName   // Paul
    nameComps.familyName   // Jobs
    nameComps.nameSuffix   // Jr.

    // It can also be configured to format your names
    // Default (same as medium), short, long or abbreviated

    nameFormatter.style = .default
    nameFormatter.string(from: nameComps)   // "Steven Jobs"

    nameFormatter.style = .short
    nameFormatter.string(from: nameComps)   // "Steven"

    nameFormatter.style = .long
    nameFormatter.string(from: nameComps)   // "Mr. Steven Paul Jobs jr."

    nameFormatter.style = .abbreviated
    nameFormatter.string(from: nameComps)   // SJ

    // It can also be use to return an attributed string using annotatedString method
    nameFormatter.style = .long
    nameFormatter.annotatedString(from: nameComps)   // "Mr. Steven Paul Jobs jr."
}

ここに画像の説明を入力してください

編集/更新:

Swift 5以降

文字列を文字以外の文字で分割する場合は、新しいCharacterプロパティを使用できますisLetter

let fullName = "First Last"

let components = fullName.split{ !$0.isLetter }
print(components)  // "["First", "Last"]\n"

1
@DarrellRootは、部分文字列をマップする必要があるだけですfullName.split { $0.isWhitespace }.map(String.init)
Leo

2
私はその新しいAPIが大好きですが、部分文字列を返すことに注意してください。私は文字let words = line.split{ $0.isWhitespace }.map{ String($0)} 列が必要だったので(そして一般的に空白で分割したかったので)これを行いました:バージョンを@LeoDabusに感謝します(元のコメントにはコードがありませんでした)。また、Swift 5バージョンを回答の先頭に移動することをお勧めします。
ダレルルート

53

WMiosの答えの代わりに、あなたも使うことができます componentsSeparatedByCharactersInSet。これは、セパレーター(空白、コンマなど)が多い場合に便利です。

あなたの特定の入力で:

let separators = NSCharacterSet(charactersInString: " ")
var fullName: String = "First Last";
var words = fullName.componentsSeparatedByCharactersInSet(separators)

// words contains ["First", "Last"]

複数のセパレータを使用する:

let separators = NSCharacterSet(charactersInString: " ,")
var fullName: String = "Last, First Middle";
var words = fullName.componentsSeparatedByCharactersInSet(separators)

// words contains ["Last", "First", "Middle"]

2
私の見解では、最も有用な答えです。文字列を,;またはその他の区切り文字で区切ることができるからです
Chris

49

スウィフト4

let words = "these words will be elements in an array".components(separatedBy: " ")

34

空白の問題

一般的に、人々はこの問題と悪い解決策を何度も作り直しています。ここはスペースですか?「」および「\ n」、「\ t」、または目に見えないため、見たことのないユニコードの空白文字についてはどうでしょうか。あなたは逃げることができますが

弱い解決策

import Foundation
let pieces = "Mary had little lamb".componentsSeparatedByString(" ")

現実を把握する必要がある場合は、文字列または日付に関するWWDCビデオをご覧ください。要するに、Appleがこの種のありふれた仕事を解決できるようにする方が、ほとんどの場合より良いのです。

堅牢なソリューション:NSCharacterSetを使用する

これを正しく行う方法であるIMHOは、NSCharacterSet前述のとおり、空白が期待どおりではない場合があり、Appleが空白文字セットを提供しているために使用します。提供されているさまざまな文字セットを調べるには、AppleのNSCharacterSet開発者向けドキュメントを確認してから、必要に応じて新しい文字セットを追加または作成してください。

NSCharacterSetホワイトスペース

Unicodeの一般的なカテゴリZの文字と文字列(U + 0009)を含む文字セットを返します。

let longerString: String = "This is a test of the character set splitting system"
let components = longerString.components(separatedBy: .whitespaces)
print(components)

2
同意した。「」で分割された回答を見た後、最初に私に起こったのは、入力テキストに複数の連続するスペースが含まれている場合はどうなりますか?タブがある場合はどうなりますか?全角(CJK)スペース?etc.
ニコラミアリ

31

スウィフト4.2とXcode 10

//This is your str
let str = "This is my String" //Here replace with your string

オプション1

let items = str.components(separatedBy: " ")//Here replase space with your value and the result is Array.
//Direct single line of code
//let items = "This is my String".components(separatedBy: " ")
let str1 = items[0]
let str2 = items[1]
let str3 = items[2]
let str4 = items[3]
//OutPut
print(items.count)
print(str1)
print(str2)
print(str3)
print(str4)
print(items.first!)
print(items.last!)

オプション2

let items = str.split(separator: " ")
let str1 = String(items.first!)
let str2 = String(items.last!)
//Output
print(items.count)
print(items)
print(str1)
print(str2)

オプション3

let arr = str.split {$0 == " "}
print(arr)

オプション4

let line = "BLANCHE:   I don't want realism. I want magic!"
print(line.split(separator: " "))
// Prints "["BLANCHE:", "I", "don\'t", "want", "realism.", "I", "want", "magic!"]"

アップルのドキュメント...

let line = "BLANCHE:   I don't want realism. I want magic!"
print(line.split(separator: " "))
// Prints "["BLANCHE:", "I", "don\'t", "want", "realism.", "I", "want", "magic!"]"

print(line.split(separator: " ", maxSplits: 1))//This can split your string into 2 parts
// Prints "["BLANCHE:", "  I don\'t want realism. I want magic!"]"

print(line.split(separator: " ", maxSplits: 2))//This can split your string into 3 parts

print(line.split(separator: " ", omittingEmptySubsequences: false))//array contains empty strings where spaces were repeated.
// Prints "["BLANCHE:", "", "", "I", "don\'t", "want", "realism.", "I", "want", "magic!"]"

print(line.split(separator: " ", omittingEmptySubsequences: true))//array not contains empty strings where spaces were repeated.
print(line.split(separator: " ", maxSplits: 4, omittingEmptySubsequences: false))
print(line.split(separator: " ", maxSplits: 3, omittingEmptySubsequences: true))

23

Swift 4では、文字列を分割するのがはるかに簡単になりました。文字列に新しい分割関数を使用するだけです。

例: let s = "hi, hello" let a = s.split(separator: ",") print(a)

これで、「hi」と「hello」の配列ができました。


これは文字列の配列を返さず、使いにくいサブ文字列の配列を返すことに注意してください。
Lirik

19

Swift 5のアップデートと最も簡単な方法

let paragraph = "Bob hit a ball, the hit BALL flew far after it was hit. Hello! Hie, How r u?"

let words = paragraph.components(separatedBy: [",", " ", "!",".","?"])

これは印刷します、

["Bob"、 "hit"、 "a"、 "ball"、 ""、 "the"、 "hit"、 "BALL"、 "flew"、 "far"、 "after"、 "it"、 "was" 「、「ヒット」、「」、「こんにちは」、「」、「ヒエ」、「」、「ハウ」、「r」、「u」、「」]

ただし、空の文字列を除外する場合は、

let words = paragraph.components(separatedBy: [",", " ", "!",".","?"]).filter({!$0.isEmpty})

出力、

[「ボブ」、「ヒット」、「a」、「ボール」、「ザ」、「ヒット」、「ボール」、「飛んだ」、「遠い」、「後」、「それ」、「だった」、「 hit」、「Hello」、「Hie」、「How」、「r」、「u」]

しかし、財団が輸入されていることを確認してください


17

スウィフト3

let line = "AAA    BBB\t CCC"
let fields = line.components(separatedBy: .whitespaces).filter {!$0.isEmpty}
  • 3つの文字列を返しAAABBBそしてCCC
  • 空のフィールドを除外します
  • 複数のスペースと集計文字を処理します
  • 新しい行を処理したい場合は.whitespaces.whitespacesAndNewlines

15

Swift 4、Xcode 10、iOS 12 Update 100%機能

let fullName = "First Last"    
let fullNameArr = fullName.components(separatedBy: " ")
let firstName = fullNameArr[0] //First
let lastName = fullNameArr[1] //Last

詳細については、こちらのAppleのドキュメントを参照してください。


13

Xcode 8.0 / Swift 3

let fullName = "First Last"
var fullNameArr = fullName.components(separatedBy: " ")

var firstname = fullNameArr[0] // First
var lastname = fullNameArr[1] // Last

長い道のり:

var fullName: String = "First Last"
fullName += " " // this will help to see the last word

var newElement = "" //Empty String
var fullNameArr = [String]() //Empty Array

for Character in fullName.characters {
    if Character == " " {
        fullNameArr.append(newElement)
        newElement = ""
    } else {
        newElement += "\(Character)"
    }
}


var firsName = fullNameArr[0] // First
var lastName = fullNameArr[1] // Last

9

分割する文字列に複数の制御文字が含まれる可能性があるシナリオがありました。これらの配列を維持するのではなく、私はAppleにその部分を処理させるだけです。

以下は、iOS 10上のSwift 3.0.1で動作します。

let myArray = myString.components(separatedBy: .controlCharacters)

8

興味深いケースを見つけました

方法1

var data:[String] = split( featureData ) { $0 == "\u{003B}" }

このコマンドを使用して、サーバーからロードされたデータからいくつかのシンボルを分割したときと、シミュレーターでテスト中に分割してテストデバイスと同期でき、パブリッシュアプ​​リやアドホックでは分割されません

このエラーを追跡するにはかなりの時間がかかります。Swiftのバージョン、iOSのバージョン、またはどちらからも呪われていない可能性があります

stringByRemovingPercentEncodingを試してもまだ機能しないため、HTMLコードに関するものではありません。

追加10/10/2015

Swift 2.0では、このメソッドは

var data:[String] = featureData.split {$0 == "\u{003B}"}

方法2

var data:[String] = featureData.componentsSeparatedByString("\u{003B}")

このコマンドを使用すると、サーバーからロードしたものと同じデータを正しく分割できます


結論、私は本当に方法2を使用することをお勧めします

string.componentsSeparatedByString("")

1
これは、ほとんどが既存の回答に関する解説であるため、「回答なし」ステータスに近いと思います。しかし、それは重要なことを指摘しています。
rickster

8

ない-これらの答えのほとんどは、入力にスペース含まれていると白のスペース、およびその時単一のスペースを。安全にその仮定を立てることができれば、受け入れられた回答(ベネットから)は非常にエレガントであり、可能な場合は私が使用する方法もそうです。

その仮定を行うことができない場合、より堅牢なソリューションは、ここでほとんどの回答が考慮しない次の状況をカバーする必要があります。

  • タブ/改行/スペース(空白)、繰り返しの文字を含む
  • 先頭/末尾の空白
  • Apple / Linux(\nおよび Windows(\r\n)の改行文字

これらのケースをカバーするために、このソリューションは正規表現を使用してすべての空白(繰り返し文字とWindowsの改行文字を含む)を1つのスペースに変換し、トリムしてから1つのスペースで分割します。

スウィフト3:

let searchInput = "  First \r\n \n \t\t\tMiddle    Last "
let searchTerms = searchInput 
    .replacingOccurrences(
        of: "\\s+",
        with: " ",
        options: .regularExpression
    )
    .trimmingCharacters(in: .whitespaces)
    .components(separatedBy: " ")

// searchTerms == ["First", "Middle", "Last"]

6

または、クロージャーなしでSwift 2でこれを行うことができます:

let fullName = "First Last"
let fullNameArr = fullName.characters.split(" ")
let firstName = String(fullNameArr[0])

6

Swift 4で文字列を配列に分割する手順。

  1. 文字列を割り当てる
  2. @分割に基づいています。

注:variableName.components(separatedBy: "split keyword")

let fullName: String = "First Last @ triggerd event of the session by session storage @ it can be divided by the event of the trigger."
let fullNameArr = fullName.components(separatedBy: "@")
print("split", fullNameArr)

4

スウィフト4

let string = "loremipsum.dolorsant.amet:"

let result = string.components(separatedBy: ".")

print(result[0])
print(result[1])
print(result[2])
print("total: \(result.count)")

出力

loremipsum
dolorsant
amet:
total: 3

3

「Hello World」という名前の変数があり、それを分割して2つの異なる変数に格納する場合は、次のように使用できます。

var fullText = "Hello World"
let firstWord = fullText.text?.components(separatedBy: " ").first
let lastWord = fullText.text?.components(separatedBy: " ").last

2
let str = "one two"
let strSplit = str.characters.split(" ").map(String.init) // returns ["one", "two"]

Xcode 7.2(7C68)


2

Swift 2.2 エラー処理とCapitalizedString追加:

func setFullName(fullName: String) {
    var fullNameComponents = fullName.componentsSeparatedByString(" ")

    self.fname = fullNameComponents.count > 0 ? fullNameComponents[0]: ""
    self.sname = fullNameComponents.count > 1 ? fullNameComponents[1]: ""

    self.fname = self.fname!.capitalizedString
    self.sname = self.sname!.capitalizedString
}

2

他の回答からわかるように、文字列の処理は依然としてSwiftの課題であり、大幅に変化し続けています。うまくいけば物事は落ち着き、それはより簡単になります。これは、現在のバージョン3.0のSwiftで複数の区切り文字を使用する方法です。

スウィフト3:

let chars = CharacterSet(charactersIn: ".,; -")
let split = phrase.components(separatedBy: chars)

// Or if the enums do what you want, these are preferred. 
let chars2 = CharacterSet.alphaNumerics // .whitespaces, .punctuation, .capitalizedLetters etc
let split2 = phrase.components(separatedBy: chars2)

2

空のシーケンスが結果の配列に含まれているPHPのようなお粗末な分割を探していましたが、これは私にとってはうまくいきexplodeました:

"First ".split(separator: " ", maxSplits: 1, omittingEmptySubsequences: false)

出力:

["First", ""]

2

これは分割された部分の配列直接与えます

var fullNameArr = fullName.components(separatedBy:" ")

このように使用できます

var firstName: String = fullNameArr[0]
var lastName: String? = fullnameArr[1]

2

split正解のみです。2つ以上のスペースの違いは次のとおりです。

var temp = "Hello world     ni hao"
let arr  = temp.components(separatedBy: .whitespacesAndNewlines)
// ["Hello", "world", "", "", "", "", "ni", "hao"]
let arr2 = temp.components(separatedBy: " ")
// ["Hello", "world", "", "", "", "", "ni", "hao"]
let arr3 = temp.split(whereSeparator: {$0 == " "})
// ["Hello", "world", "ni", "hao"]

1

これはBeta 5で再び変更されました。CollectionTypeのメソッドになりました

古い:

var fullName = "First Last"
var fullNameArr = split(fullName) {$0 == " "}

新着:

var fullName = "First Last"
var fullNameArr = fullName.split {$0 == " "}

りんごリリースノート


1

Swift 2、XCode 7.1の場合:

let complete_string:String = "Hello world"
let string_arr =  complete_string.characters.split {$0 == " "}.map(String.init)
let hello:String = string_arr[0]
let world:String = string_arr[1]

1

これは私が作成したばかりのアルゴリズムです。これは配列からaで分割し、分割StringされCharacterた文字を含む部分文字列を保持したい場合は、swallowパラメーターをに設定できますtrue

Xcode 7.3-Swift 2.2:

extension String {

    func splitBy(characters: [Character], swallow: Bool = false) -> [String] {

        var substring = ""
        var array = [String]()
        var index = 0

        for character in self.characters {

            if let lastCharacter = substring.characters.last {

                // swallow same characters
                if lastCharacter == character {

                    substring.append(character)

                } else {

                    var shouldSplit = false

                    // check if we need to split already
                    for splitCharacter in characters {
                        // slit if the last character is from split characters or the current one
                        if character == splitCharacter || lastCharacter == splitCharacter {

                            shouldSplit = true
                            break
                        }
                    }

                    if shouldSplit {

                        array.append(substring)
                        substring = String(character)

                    } else /* swallow characters that do not equal any of the split characters */ {

                        substring.append(character)
                    }
                }
            } else /* should be the first iteration */ {

                substring.append(character)
            }

            index += 1

            // add last substring to the array
            if index == self.characters.count {

                array.append(substring)
            }
        }

        return array.filter {

            if swallow {

                return true

            } else {

                for splitCharacter in characters {

                    if $0.characters.contains(splitCharacter) {

                        return false
                    }
                }
                return true
            }
        }
    }
}

例:

"test text".splitBy([" "]) // ["test", "text"]
"test++text--".splitBy(["+", "-"], swallow: true) // ["test", "++" "text", "--"]
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.