Swift - Розбийте рядок на кілька рядків


265

Як я можу розділити рядок на кілька рядків, таких як нижче?

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

Для автоматичного перетворення рядків у багаторядковий рядок, дивіться мою відповідь на цей трохи пов'язаний потік Як ви можете реалізувати цей багаторядковий рядковий макрос макрос у Swift?
holroy

Відповіді:


444

Swift 4 включає підтримку багаторядкових літеральних рядків . Окрім нових рядків, вони також можуть містити несказані цитати.

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

Старіші версії Swift не дозволяють мати один літерал у кількох рядках, але ви можете додавати літерали разом у кількох рядках:

var text = "This is some text\n"
         + "over multiple lines\n"

2
Проблема з таким підходом полягає в тому, що ви можете легко досягти занадто багато "продовжених" рядків у Swift (станом на Xcode 6.2 beta), де він скаржиться на вираз "занадто складний, щоб його можна було вирішити за розумну кількість часу" і розглянути можливість його розриву це зводиться до більш простих виразів. Це некрасиво, але досить просто для виконання, просто загортайте секції в парени.
clearlight

8
Не забудьте додати пробіл між кінцевою цитатою та знаком +, інакше ви отримаєте помилку "" + "не оператор постфікса унарного"
Орлін Георгієв,

Це все ще працює, але вам потрібно вручну додати \nсимвол. Наприклад, у REPL: println("foo\n" + "bar")друкує fooта barна окремих рядках.
Брайан Герстл

Це має бути зафіксовано в Xcode 7 "Об'єднання літеральних рядків Swift, у тому числі в декількох рядках, - це гарантована оптимізація часу компіляції навіть у -Onone." Adcdownload.apple.com/WWDC_2015/Xcode_7_beta/…
Костянтин Коваль

2
Не працює для значень регістру, що використовують рядки :(
Ларс Блюмберг,

32

Я використовував розширення на String, щоб досягти багаторядкових рядків, уникаючи помилки підвішування компілятора. Це також дозволяє вказати роздільник, щоб ви могли використовувати його трохи як функцію приєднання 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!"

1
Ці методи ідеальні. Навіть в останньому 1.2 версії Swift довгі літерали збираються дуже повільно, і ці методи уникають цих витрат.
phatmann

2
Для всіх, хто використовує Swift 2, enumerate(lines)заразlines.enumerate()
Jedidja

2
@mcornell Це приємно, але чи не joinWithSeparatorробить по суті те саме? ["Hello", "World!"].joinWithSeparator(", ")
Dan Loewenherz

27

Це було перше невтішне про Свіфта, яке я помітив. Практично всі мови сценаріїв дозволяють створювати багаторядкові рядки.

C ++ 11 додав необроблені рядкові літерали, які дозволяють визначити власний термінатор

У C # є @literals для багаторядкових рядків.

Навіть звичайний C, а отже, старомодний C ++ і Objective-C, дозволяють досягти стимуляції, просто поставивши декілька суміжних літералів поруч, тому лапки згортаються. Пробіл не враховується, коли ви це зробите, щоб ви могли розміщувати їх у різних рядках (але потрібно додати власні нові рядки):

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

Оскільки швидкий не знає, що ви розмістили текст у декількох рядках, я повинен виправити зразок коннора, аналогічно моєму зразку C, експліцитно вказавши новий рядок:

var text:String = "This is some text \n" +
                  "over multiple lines"

4
Я досить впевнений, що в цьому є обмеження. Я спробував розділити рядок на 13 рядків (це багаторядковий текст інформації). Він не тільки не зміг закінчити компіляцію, але й підвів мого Mac на коліна. Як я кажу, я не можу категорично сказати, що це проблема, але будьте обережні, вплив є досить поганим.
Дерек Найт

Я перебивав кілька разів ще до того, як компілювати. Я думаю, що процес «SourceKitService», який відповідає за підсвічування синтаксису та завершення коду (я вважаю), також відповідає за цю збій.
Paul Brewczynski

@DerekKnight Це помилка компілятора, а не обмеження мови. Якщо це все ще зберігається, слід подати радар.
radex

@bluesm FYI: SourceKit - це окремий процес, тому він не може збити Xcode. Це підкреслює синтаксис та доповнення коду, правильно, але на даний момент сама компіляція живе в процесі Xcode - ось чому помилка компілятора іноді знімає Xcode із себе :(
radex

17

У Swift 4.0 можливі багаторядкові рядки, але є деякі правила:

  1. Ви повинні почати і закінчити свої рядки з трьома подвійними лапками, """.
  2. Вміст рядка повинен починатись у власному рядку.
  3. Закінчення """також повинно починатися на власній лінії.

Крім цього, ви добре піти! Ось приклад:

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!
"""

Дізнайтеся, що нового у Swift 4 для отримання додаткової інформації.


На жаль, це не працює на ігровому майданчику Xcode 8.3.3. Я отримую помилку "невизначений рядок".
Джеймс Фостер

Як я вже говорив, ця функція нова в Swift 4 - або встановіть інструментальну
мережу

16

Як вказує litso, повторне використання +-Operator в одному виразі може призвести до вивішування бета-версії XCode (щойно перевірено за допомогою XCode 6 Beta 5): Xcode 6 Beta не компілюється

Альтернативою для рядкових рядків на даний момент є використання масиву рядків і reduceце з +:

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

Або, мабуть, простіше, використовуючи join:

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

Версія скорочення працювала для мене на бета-версії 6, але приєднання кинуло виняток.
Трістан Уорнер-Сміт

9

Swift 4 вирішив це питання, надавши підтримку багаторядкової літеральної лінійки. Щоб почати рядковий літерал, додайте три подвійні позначки ланок (”” ”) і натисніть клавішу повернення. Після натискання клавіші повернення починайте писати рядки з будь-якими змінними, розривами рядків і подвійними лапками. як ви писали в блокноті чи будь-якому текстовому редакторі. Для закінчення багаторядкового рядкового літералу знову напишіть (”” ”) у новий рядок.

Дивіться нижче приклад

     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)

5

Швидкий:

@connor - це правильна відповідь, але якщо ви хочете додати рядки у друкованому виписці, те, що ви шукаєте, є \nта / або \r, це називається Escape Sequences або Escaped Characters, це посилання на документацію Apple з цієї теми. .

Приклад:

print("First line\nSecond Line\rThirdLine...")

6
Цього не хоче хтось. Ми хочемо мати можливість мати обертання рядків у вихідному коді для рядкових літералів, а не (обов'язково) мати розриви рядків у виведеному виході . Це було досить зрозуміло в оригінальному питанні. Люди з позитивними оцінками очевидно зрозуміли. Люди з негативними балами, очевидно, цього не зробили.
ArtOfWarfare

5
@ArtOfWarfare - це відповідь, яку я шукав, і ця сторінка була найкращим результатом при пошуку "швидкої швидкої строки". Очевидно, це не так очевидно, як ви говорите.
Джон Р Перрі

4

Додавши до @Connor відповідь, також має бути \ n. Ось переглянений код:

var text:String = "This is some text \n" +
                  "over multiple lines"

3

У наступному прикладі зображено багаторядкове продовження, використовуючи дужки як просте вирішення помилки Swift від Xcode 6.2 Beta, де він скаржиться на вираз занадто складний, щоб вирішити за розумну кількість часу та розглянути можливість його розбиття на менший шматки:

    .
    .
    .
    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)
    .
    .
    .

0

Інший спосіб, якщо ви хочете використовувати змінну рядка з деяким заздалегідь визначеним текстом,

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

0

Ви можете використовувати Unicode рівних для введення або \nвпровадити їх всередині вашого рядка. Наприклад: \u{0085}.


0

Зразок

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

У разі якщо ви не вважаєте + оператора підходящим


0

Один із підходів полягає у встановленні тексту мітки на attributedText та оновлення змінної рядка для включення HTML для розриву рядка ( <br />).

Наприклад:

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

Вихід:

This is some text
over multiple lines

Сподіваюсь, це допомагає!


Ви не можете призначити Stringзначення (текст) NSAttributedString?властивості (label.attributedText).
Максим

0

Ось фрагмент коду для розділення рядка на n символів, розділених по рядках:

//: 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
            }
        }

    }
}

-3

Я спробував декілька способів, але знайшов ще краще рішення: просто використовуйте елемент «Перегляд тексту». Це текст відображається декілька рядків автоматично! Знайдено тут: декілька рядків UITextField


(Тільки так ви знаєте, downvotes, ймовірно , тому , що мова йшла про форматування в коді, а не в призначеному для користувача інтерфейсі ... і надання зразка коду в вашій відповіді, ймовірно , зробив це більш очевидне)
BENC
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.