Swift - Membagi string menjadi beberapa baris

Jawaban:

444

Swift 4 termasuk dukungan untuk string multi-line literal . Selain baris baru, mereka juga dapat berisi kutipan yang tidak terhindar.

var text = """
    This is some text
    over multiple lines
    """

Versi Swift yang lebih lama tidak memungkinkan Anda untuk memiliki satu literal lebih dari beberapa baris tetapi Anda dapat menambahkan literal bersama-sama melalui beberapa baris:

var text = "This is some text\n"
         + "over multiple lines\n"
Connor
sumber
2
Masalahnya dengan pendekatan itu adalah Anda dapat dengan mudah menjangkau terlalu banyak baris 'lanjutan' di Swift (pada Xcode 6.2 beta), di mana ia mengeluh ungkapannya "terlalu rumit untuk dipecahkan dalam jumlah waktu yang wajar" dan untuk mempertimbangkan melanggar itu ke ekspresi yang lebih sederhana. Itu jelek tapi cukup mudah untuk diselesaikan, cukup bungkus bagian-bagiannya di parens.
clearlight
8
Jangan lupa untuk menambahkan spasi antara kutipan penutup dan +, jika tidak Anda akan mendapatkan kesalahan "'+' bukan operator unary postfix"
Orlin Georgiev
Ini masih berfungsi, tetapi Anda perlu menambahkan \nkarakter secara manual . Misalnya, dalam REPL: println("foo\n" + "bar")cetakan foodan barpada baris yang terpisah.
Brian Gerstle
Itu harus diperbaiki di Xcode 7 "Rangkaian literasi string Swift, termasuk lintas banyak baris, adalah optimisasi waktu kompilasi yang dijamin, bahkan di -Onone.," Adcdownload.apple.com/WWDC_2015/Xcode_7_beta/…
Kostiantyn Koval
2
Tidak berfungsi untuk nilai kasus enum yang menggunakan string :(
Lars Blumberg
32

Saya menggunakan ekstensi pada String untuk mencapai string multiline sambil menghindari bug menggantung kompiler. Ini juga memungkinkan Anda untuk menentukan pemisah sehingga Anda dapat menggunakannya sedikit seperti fungsi gabungan Python

extension String {
    init(sep:String, _ lines:String...){
        self = ""
        for (idx, item) in lines.enumerated() {
            self += "\(item)"
            if idx < lines.count-1 {
                self += sep
            }
        }
    }

    init(_ lines:String...){
        self = ""
        for (idx, item) in lines.enumerated() {
            self += "\(item)"
            if idx < lines.count-1 {
                self += "\n"
            }
        }
    }
}



print(
    String(
        "Hello",
        "World!"
    )
)
"Hello
World!"

print(
    String(sep:", ",
        "Hello",
        "World!"
    )
)
"Hello, World!"
mcornell
sumber
1
Metode-metode ini sempurna. Bahkan dalam rilis Swift 1.2 terbaru literal panjang mengkompilasi sangat lambat, dan metode ini menghindari overhead itu.
phatmann
2
Bagi siapa pun yang menggunakan Swift 2, enumerate(lines)sekaranglines.enumerate()
Jedidja
2
@ Cornell Ini bagus, tetapi joinWithSeparatorpada dasarnya tidak melakukan hal yang sama? ["Hello", "World!"].joinWithSeparator(", ")
Dan Loewenherz
27

Ini adalah hal mengecewakan pertama tentang Swift yang saya perhatikan. Hampir semua bahasa scripting memungkinkan untuk string multi-line.

C ++ 11 menambahkan literal string mentah yang memungkinkan Anda untuk menentukan terminator Anda sendiri

C # memiliki @ literer untuk string multi-line.

Bahkan C sederhana dan C-kuno dan Objective-C kuno memungkinkan untuk concatentation hanya dengan menempatkan beberapa literal yang berdekatan, sehingga kutipan diciutkan. Spasi tidak dihitung saat Anda melakukannya sehingga Anda dapat menempatkannya di baris yang berbeda (tetapi perlu menambahkan baris baru Anda sendiri):

const char* text = "This is some text\n"
                   "over multiple lines";

Karena swift tidak tahu Anda telah meletakkan teks Anda di beberapa baris, saya harus memperbaiki sampel connor, mirip dengan sampel C saya, secara eksplisit menyatakan baris baru:

var text:String = "This is some text \n" +
                  "over multiple lines"
Andy Dent
sumber
4
Saya cukup yakin ada batasan dalam hal ini. Saya telah mencoba memisahkan string lebih dari 13 baris (Ini adalah teks info multi baris) Tidak hanya gagal menyelesaikan kompilasi, tetapi juga membuat Mac saya bertekuk lutut. Seperti yang saya katakan, saya tidak bisa mengatakan ini adalah masalah, tapi hati-hati, dampaknya sangat buruk.
Derek Knight
Saya telah jatuh beberapa kali bahkan sebelum kompilasi. Saya pikir proses "SourceKitService" yang bertanggung jawab untuk highlight sintaks dan penyelesaian kode (saya kira) bertanggung jawab untuk crash ini juga.
Paul Brewczynski
@DerekKnight Itu adalah bug penyusun, bukan batasan bahasa. Jika masih berlanjut, Anda harus mengajukan Radar.
radex
@bluesm FYI: SourceKit adalah proses yang terpisah, sehingga tidak bisa crash Xcode. Itu menyoroti sintaks dan penyelesaian kode, benar, tetapi saat ini, kompilasi itu sendiri hidup dalam proses Xcode - itu sebabnya bug kompilator mencatat Xcode dengan dirinya sendiri kadang-kadang :(
radex
17

String multi-garis dimungkinkan pada Swift 4.0, tetapi ada beberapa aturan:

  1. Anda harus memulai dan mengakhiri string Anda dengan tiga tanda kutip ganda """,.
  2. Konten string Anda harus dimulai pada barisnya sendiri.
  3. Mengakhiri itu """ juga harus dimulai dari jalurnya sendiri.

Selain itu, Anda baik untuk pergi! Ini sebuah contoh:

let longString = """
When you write a string that spans multiple
lines make sure you start its content on a
line all of its own, and end it with three
quotes also on a line of their own.
Multi-line strings also let you write "quote marks"
freely inside your strings, which is great!
"""

Lihat apa yang baru di Swift 4 untuk informasi lebih lanjut.

TwoStraws
sumber
Sayangnya ini tidak berfungsi di Playground Xcode 8.3.3. Saya mendapatkan kesalahan "string tidak tertentu".
James Foster
Seperti yang saya katakan, fitur ini baru di Swift 4 - baik instal toolchain Swift 4 ke Xcode 8.3.3 atau instal Xcode 9.
TwoStraws
16

Seperti yang ditunjukkan oleh litso, penggunaan berulang dari +-Operator dalam satu ekspresi dapat menyebabkan XCode Beta hang (hanya diperiksa dengan XCode 6 Beta 5): Xcode 6 Beta tidak mengkompilasi

Alternatif untuk string multiline untuk saat ini adalah menggunakan array string dan reducedengan +:

var text = ["This is some text ",
            "over multiple lines"].reduce("", +)

Atau, bisa dibilang lebih sederhana, menggunakan join:

var text = "".join(["This is some text ",
                    "over multiple lines"])
Jonas Reinsch
sumber
Versi pengurangan bekerja untuk saya pada beta 6, tetapi bergabung melemparkan pengecualian.
Tristan Warner-Smith
9

Swift 4 telah mengatasi masalah ini dengan memberikan dukungan multi-string string literal. Untuk memulai string literal tambahkan tiga tanda kutip ganda ("" ") dan tekan tombol kembali, Setelah menekan tombol kembali mulailah menulis string dengan variabel apa pun, jeda baris, dan tanda kutip ganda saja seperti Anda akan menulis di notepad atau editor teks apa pun. Untuk mengakhiri multi-string string literal lagi tulis ("" ") di baris baru.

Lihat Contoh Di Bawah Ini

     let multiLineStringLiteral = """
    This is one of the best feature add in Swift 4
    It let’s you write “Double Quotes” without any escaping
    and new lines without need of “\n”
    """

print(multiLineStringLiteral)
Nareshkumar Nil
sumber
5

Cepat:

@connor adalah jawaban yang tepat, tetapi jika Anda ingin menambahkan baris dalam pernyataan cetak apa yang Anda cari \ndan / atau \r, ini disebut Escape Sequences atau Escaped Characters, ini adalah tautan ke dokumentasi Apple tentang topik tersebut. .

Contoh:

print("First line\nSecond Line\rThirdLine...")
Juan Boero
sumber
6
Ini bukan yang diinginkan siapa pun. Kami ingin dapat memiliki garis pembungkus dalam kode sumber untuk string literal, tidak (harus) memiliki garis istirahat dalam output yang diberikan . Ini cukup jelas dalam pertanyaan awal, saya pikir. Orang dengan skor positif jelas mengerti. Orang dengan skor negatif jelas tidak.
ArtOfWarfare
5
@ArtOfWarfare ini adalah jawaban yang saya cari dan halaman ini adalah hasil teratas ketika melakukan pencarian untuk "new line swift string". Jelas, itu tidak sejelas yang Anda katakan.
John R Perry
4

Menambahkan ke @Connor jawaban, perlu ada \ n juga. Berikut kode yang direvisi:

var text:String = "This is some text \n" +
                  "over multiple lines"
Pandurang Yachwad
sumber
3

Contoh berikut menggambarkan kelanjutan multi-baris, menggunakan tanda kurung sebagai solusi sederhana untuk bug Swift pada Xcode 6.2 Beta, di mana ia mengeluh ekspresi terlalu rumit untuk diselesaikan dalam jumlah waktu yang wajar, dan untuk mempertimbangkan memecahnya menjadi lebih kecil potongan:

    .
    .
    .
    return String(format:"\n" +
                    ("    part1:    %d\n"    +
                     "    part2:    %d\n"    +
                     "    part3:  \"%@\"\n"  +
                     "    part4:  \"%@\"\n"  +
                     "    part5:  \"%@\"\n"  +
                     "    part6:  \"%@\"\n") +
                    ("    part7:  \"%@\"\n"  +
                     "    part8:  \"%@\"\n"  +
                     "    part9:  \"%@\"\n"  +
                     "    part10: \"%@\"\n"  +
                     "    part12: \"%@\"\n") +
                     "    part13:  %f\n"     +
                     "    part14:  %f\n\n",
                    part1, part2, part3, part4, part5, part6, part7, part8, 
                    part9, part10, part11, part12, part13, part14)
    .
    .
    .
cahaya terang
sumber
0

Cara lain jika Anda ingin menggunakan variabel string dengan beberapa teks yang telah ditentukan,

var textFieldData:String = "John"
myTextField.text = NSString(format: "Hello User, \n %@",textFieldData) as String
myTextField.numberOfLines = 0
Zoran777
sumber
0

Anda dapat menggunakan unicode sama dengan untuk masuk atau \ndan menerapkannya di dalam string Anda. Sebagai contoh: \u{0085}.

hooman
sumber
0

Sampel

var yourString = "first line \n second line \n third line"

Dalam hal ini, Anda tidak menemukan operator + yang cocok

Danielle Cohen
sumber
0

Salah satu pendekatan adalah mengatur teks label ke attributedText dan memperbarui variabel string untuk menyertakan HTML untuk jeda baris (<br /> ).

Sebagai contoh:

var text:String = "This is some text<br />over multiple lines"
label.attributedText = text

Keluaran:

This is some text
over multiple lines

Semoga ini membantu!

B-Rad
sumber
Anda tidak dapat menetapkan Stringnilai (teks) ke NSAttributedString?properti (label.attributedText).
Maxime Ashurov
0

Berikut ini cuplikan kode untuk membagi string dengan n karakter yang dipisahkan oleh baris:

//: A UIKit based Playground for presenting user interface

import UIKit
import PlaygroundSupport

class MyViewController : UIViewController {
    override func loadView() {

        let str = String(charsPerLine: 5, "Hello World!")
        print(str) // "Hello\n Worl\nd!\n"

    }
}

extension String {

    init(charsPerLine:Int, _ str:String){

        self = ""
        var idx = 0
        for char in str {
            self += "\(char)"
            idx = idx + 1
            if idx == charsPerLine {
                self += "\n"
                idx = 0
            }
        }

    }
}
Michael N
sumber
-3

Saya mencoba beberapa cara tetapi menemukan solusi yang lebih baik: Cukup gunakan elemen "Tampilan Teks". Teksnya muncul beberapa baris secara otomatis! Ditemukan di sini: UITextField beberapa baris

Oliver Ries
sumber
(Asal tahu saja, downvotes mungkin karena pertanyaannya adalah tentang memformat dalam kode, bukan di UI ... dan memberikan sampel kode dalam jawaban Anda mungkin akan membuat ini lebih jelas)
benc