Swift - แยกสตริงผ่านหลายบรรทัด


265

ฉันจะแบ่งสตริงออกเป็นหลายบรรทัดเช่นด้านล่างได้อย่างไร

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

เมื่อต้องการแปลงบรรทัดเป็นสตริงแบบหลายบรรทัดโดยอัตโนมัติดูคำตอบของฉันในหัวข้อที่เกี่ยวข้องเล็กน้อยนี้คุณจะใช้แมโครตัวอักษรสตริงหลายบรรทัดใน Swift ได้อย่างไร
holroy

คำตอบ:


444

สวิฟท์ 4 รวมถึงการสนับสนุนตัวอักษรของสตริงหลายคู่สาย นอกเหนือจากการขึ้นบรรทัดใหม่พวกเขายังสามารถมีคำพูดที่ไม่ใช้ค่า Escape

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 เบต้า) ซึ่งมันบ่นการแสดงออกคือ "ซับซ้อนเกินไปที่จะแก้ไขในเวลาที่สมเหตุสมผล" และพิจารณาการแตกหัก มันลงไปเพื่อการแสดงออกที่ง่ายขึ้น มันน่าเกลียด แต่ก็ง่ายพอที่จะทำให้สำเร็จ
clearlight

8
อย่าลืมเพิ่มช่องว่างระหว่างเครื่องหมายคำพูดปิดและ + มิฉะนั้นคุณจะได้รับข้อผิดพลาด "'+' ไม่ใช่ตัวดำเนินการ postary unary postfix
Orlin Georgiev

ยังใช้งานได้ แต่คุณต้องเพิ่ม\nอักขระด้วยตนเอง ตัวอย่างเช่นใน REPL: println("foo\n" + "bar")พิมพ์fooและbarแยกบรรทัด
Brian Gerstle

ควรได้รับการแก้ไขใน Xcode 7 "Concatenation ของตัวอักษรสตริง Swift ซึ่งรวมถึงหลายบรรทัดเป็นการรับประกันการปรับเวลาแบบคอมไพล์ที่รับประกันได้แม้ที่ -Onone," adcdownload.apple.com/WWDC_2015/Xcode_7_beta/ …
Kostiantyn Koval

2
ไม่ทำงานสำหรับค่าตัวพิมพ์ใหญ่ที่ใช้สตริง :(
Lars Blumberg

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 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 ของฉันไปที่หัวเข่า อย่างที่ฉันพูดฉันไม่สามารถจัดหมวดหมู่ได้ว่านี่เป็นปัญหา แต่ระวังผลกระทบนั้นแย่มาก
Derek Knight

ฉันเกิดข้อผิดพลาดหลายครั้งก่อนที่จะรวบรวม ฉันคิดว่ากระบวนการ "SourceKitService" ที่มีหน้าที่รับผิดชอบในการเน้นไวยากรณ์และการเติมโค้ด (ฉันคิดว่า) เป็นสาเหตุของความผิดพลาดนี้เช่นกัน
Paul Brewczynski

@DerekKnight นั่นเป็นข้อผิดพลาดของคอมไพเลอร์ไม่ใช่ข้อ จำกัด ทางภาษา หากยังคงมีอยู่คุณควรยื่น Radar
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 Playground ฉันได้รับข้อผิดพลาด "สตริงที่ไม่ถูกทำลาย"
James Foster

ตามที่ได้กล่าวไปแล้วฟีเจอร์นี้เป็นของใหม่ใน Swift 4 - ติดตั้ง Swift 4 toolchain ลงใน Xcode 8.3.3 หรือติดตั้ง Xcode 9
TwoStraws

16

ตามที่ระบุไว้โดย litso การใช้+-Operator ซ้ำในนิพจน์หนึ่งสามารถนำไปสู่การแขวน XCode Beta (ตรวจสอบด้วย 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 ได้แก้ไขปัญหานี้โดยให้การสนับสนุนตัวอักษรสตริงหลายบรรทัดเพื่อเริ่มต้นตัวอักษรสตริงเพิ่มเครื่องหมายคำพูดคู่ ("””) และกดปุ่มย้อนกลับสามหลังจากกดปุ่มย้อนกลับเริ่มเขียนสตริงด้วยตัวแปรใด ๆ ตัวแบ่งบรรทัดและเครื่องหมายคำพูดคู่ เหมือนที่คุณจะเขียนใน Notepad หรือโปรแกรมแก้ไขข้อความใด ๆ หากต้องการสิ้นสุดสตริงหลายบรรทัดตามตัวอักษรให้เขียน (”””) ในบรรทัดใหม่

ดูตัวอย่างด้านล่าง

     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 อักขระนี่คือลิงก์ไปยังเอกสารประกอบของ Apple ในหัวข้อ .

ตัวอย่าง:

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

6
นี่ไม่ใช่สิ่งที่ทุกคนต้องการ เราต้องการให้สามารถมีการตัดบรรทัดในซอร์สโค้ดสำหรับตัวอักษรสตริงได้ (ไม่จำเป็น) มีตัวแบ่งบรรทัดในเอาต์พุตที่เรนเดอร์ ฉันคิดว่าคำถามนี้ค่อนข้างชัดเจน ผู้ที่มีคะแนนบวกเป็นที่เข้าใจอย่างชัดเจน คนที่มีคะแนนลบไม่ชัดเจน
ArtOfWarfare

5
@ArtOfWarfare นี่คือคำตอบที่ฉันกำลังมองหาและหน้านี้เป็นผลการค้นหาอันดับต้น ๆ เมื่อทำการค้นหา "new line swift string" เห็นได้ชัดว่ามันไม่ชัดเจนอย่างที่คุณพูด
John R Perry

4

การเพิ่มคำตอบ @Connor จำเป็นต้องมี \ n ด้วย นี่คือรหัสแก้ไข:

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

3

ตัวอย่างต่อไปนี้แสดงให้เห็นถึงความต่อเนื่องหลายบรรทัดโดยใช้วงเล็บเป็นวิธีแก้ปัญหาง่ายๆสำหรับ Swift bug ณ 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

คุณสามารถใช้ยูนิโค้ดเท่ากับเพื่อป้อนหรือ\nนำไปใช้ภายในสตริงของคุณ ตัวอย่างเช่น\u{0085}.



0

วิธีการหนึ่งคือการตั้งค่าข้อความป้ายกำกับเป็น assembedText และอัปเดตตัวแปรสตริงเพื่อรวม 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)
Maxime Ashurov

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 อาจเป็นเพราะคำถามเกี่ยวกับการจัดรูปแบบในรหัสไม่ได้อยู่ใน UI ... และการให้ตัวอย่างโค้ดในคำตอบของคุณอาจทำให้สิ่งนี้ชัดเจนยิ่งขึ้น)
benc
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.