วิธีการแทรกบรรทัดใหม่ในสตริงตัวอักษร?


155

ใน. NET ฉันสามารถให้ทั้งสอง\rหรือ\nสตริงตัวอักษร แต่มีวิธีการแทรกบางอย่างเช่น "บรรทัดใหม่" อักขระพิเศษเช่นEnvironment.NewLineคุณสมบัติคงที่?


9
คำถามคืออะไร?
iburlakov

คำตอบ:


319

ตัวเลือกง่าย ๆ คือ:

  • string.Format:

    string x = string.Format("first line{0}second line", Environment.NewLine);
  • การต่อสตริง:

    string x = "first line" + Environment.NewLine + "second line";
  • การแก้ไขสตริง (ใน C # 6 ขึ้นไป):

    string x = $"first line{Environment.NewLine}second line";

คุณสามารถใช้ \ n ได้ทุกที่และแทนที่:

string x = "first line\nsecond line\nthird line".Replace("\n",
                                                         Environment.NewLine);

โปรดทราบว่าคุณไม่สามารถทำให้ค่าคงที่เป็นสตริงได้เนื่องจากค่าของEnvironment.NewLineจะพร้อมใช้งานในเวลาดำเนินการเท่านั้น


1
ขอบคุณแน่นอน แต่ฉันหมายถึงการหลีกเลี่ยงการใช้ Environment.NewLine คำถามของฉันคือถ้ามี '/ ขึ้นบรรทัดใหม่' ตามตัวอักษร
Captain Comic

2
@Captain: คุณต้องการที่จะหลีกเลี่ยงทำไมEnvironment.NewLine? มันเป็นวิธีปฏิบัติที่ดีที่จะใช้มัน
abatishchev

18
@abatishchev: ในบางแห่งมันเป็นแนวปฏิบัติที่ดี ในคนอื่น ๆ ของฉันมันไม่ได้เป็น คุณจำเป็นต้องรู้ว่าคุณต้องการใช้แพลตฟอร์มเฉพาะ ยกตัวอย่างเช่นมันไม่ได้เป็นความคิดที่ดีถ้าคุณกำลังใช้โปรโตคอลเครือข่ายที่ควรกำหนดจุดสิ้นสุดเส้นตัวเอง
Jon Skeet

1
@Captain Comic: ประโยคสุดท้ายของฉันอธิบายว่าทำไมมันจึงไม่สามารถหลบหนีได้อย่างแท้จริง - คุณไม่สามารถรวมไว้ในข้อมูลเมตาสำหรับค่าคงที่สตริงเนื่องจากไม่ใช่ค่าคงที่
Jon Skeet

1
ใช่อาจเป็นเพราะฉันลังเลที่จะทำให้ทั้งสองตัวเลือก: ตัวเลือกที่ใช้ตัวดำเนินการบวกและตัวที่สองโดยใช้รูปแบบการจัดรูปแบบนั้นค่อนข้างค่าใช้จ่ายที่ตัวอักษร '\ newline' จะเป็นวิธีที่เร็วที่สุด แต่อย่างที่จอนกล่าวว่าตัวอักษร NewLine ถ้ามีอยู่จริงจะต้องมีการเคลื่อนไหวและขึ้นอยู่กับแพลตฟอร์ม
Captain Comic

33

หากคุณต้องการสตริง const ที่มี Environment.NewLine อยู่ในนั้นคุณสามารถทำสิ่งนี้:

const string stringWithNewLine =
@"first line
second line
third line";

แก้ไข

เนื่องจากสิ่งนี้อยู่ในสตริง const จึงถูกทำในเวลาคอมไพล์ดังนั้นจึงเป็นการตีความของคอมไพเลอร์ของการขึ้นบรรทัดใหม่ ฉันดูเหมือนจะไม่พบการอ้างอิงที่อธิบายพฤติกรรมนี้ แต่ฉันสามารถพิสูจน์ได้ว่าทำงานได้ตามที่ต้องการ ฉันรวบรวมรหัสนี้ทั้งบน Windows และ Ubuntu (พร้อม Mono) จากนั้นถอดชิ้นส่วนและผลลัพธ์เหล่านี้คือ:

แยกส่วนบน Windows แยกส่วนบน Ubuntu

อย่างที่คุณเห็นในบรรทัดใหม่ของ Windows จะถูกตีความเป็น \ r \ n และบน Ubuntu เป็น \ n


1
คอมไพเลอร์จะเพิ่ม Environment.NewLine โดยอัตโนมัติระหว่างแต่ละบรรทัดในข้อความ ดังนั้นสตริงจึงถูกตีความว่าเป็น: "บรรทัดแรก" + สภาพแวดล้อม NewLine + "บรรทัดที่สอง" + สภาพแวดล้อม NewLine + "บรรทัดที่สาม"
Tal Jerome

3
+1 วิธีที่ไม่ค่อยมีคนรู้จักในการแทรกบรรทัดใหม่ในตัวอักษรสตริง มีการอ้างอิงสำหรับพฤติกรรมที่คุณระบุหรือไม่? เป็น Environment.NewLine จริงๆหรือว่าเป็นคำจำกัดความของคอมไพเลอร์ของบรรทัดใหม่
หน้าตาบูดบึ้งของ Despair

1
คุณแน่ใจหรือว่าไม่ใช่อักขระขึ้นบรรทัดใหม่ของโปรแกรมแก้ไขรหัสที่แทรกไว้ที่นั่น หากคุณคัดลอกวางรหัสนั้นลงในโปรแกรมแก้ไขบน Windows อาจเป็นไปได้ที่จะถูกแปลงเป็น \ r \ n ทำสิ่งเดียวกันบนแพลตฟอร์มที่เหมือนยูนิกซ์และมันอาจจะถูกแปลงเป็น \ n แทน
Xiyng

ระวังด้วย หากคุณชำระเงินรหัสบนเซิร์ฟเวอร์ CI / CD (เช่น Teamcity การชำระเงินด้านเซิร์ฟเวอร์) จะเปลี่ยน CRLF เป็น LF และจะไม่มีบรรทัดใหม่ในสตริง
Leszek P

13
var sb = new StringBuilder();
sb.Append(first);
sb.AppendLine(); // which is equal to Append(Environment.NewLine);
sb.Append(second);
return sb.ToString();

2
ทำไมคุณถึงทำเช่นนี้แทนที่จะใช้first + Environment.NewLine + secondสิ่งที่มีประสิทธิภาพมากกว่าและ (IMO) อ่านง่ายกว่า
Jon Skeet

@ จอน: มีประสิทธิภาพมากขึ้นจริงเหรอ? ฉันคิดว่ามันString.Formatจะสร้าง 1 สายในคราวเดียว (แต่ภายในช้าลงเล็กน้อยเนื่องจากการต่อข้อมูลเฉพาะวัฒนธรรม ฯลฯ ) ในขณะที่การต่อสายสตริง - 1 ส่งผล + 1 ชั่วคราวใช่ไหม
abatishchev

1
@abatishchev: คอมไพเลอร์แปลง STR + STR + STR เพื่อString.Concatenateที่โดยตรงสร้างเพียงหนึ่งสตริงเอาท์พุท (IIRC ถ้าสตริงที่มีตัวอักษรเรียงต่อกันจะทำในคอมไพเลอร์.
ริชาร์ด

@ ริชาร์ด: คือการเชื่อมต่อสตริงหลายตัว แต่หนึ่งบรรทัด ( "a"+b+"c"+dฯลฯ ) โดยประสิทธิภาพเท่ากับหนึ่งเดียวหรือไม่ หรือเพิ่งแปลงเป็นString.Concatenate(a,b,c,d,etc)ใช่มั้ย
abatishchev

@abatishchev: นั่นเป็นเหตุผลที่ฉันไม่ได้แนะนำstring.Formatในความคิดเห็น concatenation สตริงจะไม่ผลิตสตริงชั่วคราวใด ๆ string.Concat(first, Environment.NewLine, second)เพราะคอมไพเลอร์จะเรียก
Jon Skeet

3

อีกวิธีหนึ่งในการจัดวาง Environment.NewLine ในรูปแบบสตริง แนวคิดคือการสร้างวิธีการขยายสตริงที่จัดรูปแบบสตริงตามปกติ แต่ยังแทนที่ {nl} ในข้อความด้วย Environment.NewLine

การใช้

   " X={0} {nl} Y={1}{nl} X+Y={2}".FormatIt(1, 2, 1+2);
   gives:
    X=1
    Y=2
    X+Y=3

รหัส

    ///<summary>
    /// Use "string".FormatIt(...) instead of string.Format("string, ...)
    /// Use {nl} in text to insert Environment.NewLine 
    ///</summary>
    ///<exception cref="ArgumentNullException">If format is null</exception>
    [StringFormatMethod("format")]
    public static string FormatIt(this string format, params object[] args)
    {
        if (format == null) throw new ArgumentNullException("format");

        return string.Format(format.Replace("{nl}", Environment.NewLine), args);
    }

บันทึก

  1. หากคุณต้องการให้ ReSharper ไฮไลต์พารามิเตอร์ของคุณเพิ่มคุณสมบัติให้กับวิธีการด้านบน

    [StringFormatMethod ( "รูปแบบ")]

  2. การใช้งานนี้เห็นได้ชัดว่ามีประสิทธิภาพน้อยกว่าเพียงแค่สตริงรูปแบบ

  3. บางทีใครที่สนใจในคำถามนี้ก็อาจสนใจคำถามต่อไปด้วยเช่นกัน: การจัดรูปแบบสตริงใน C #


2
string myText =
    @"<div class=""firstLine""></div>
      <div class=""secondLine""></div>
      <div class=""thirdLine""></div>";

นั่นไม่ใช่:

string myText =
@"<div class=\"firstLine\"></div>
  <div class=\"secondLine\"></div>
  <div class=\"thirdLine\"></div>";

1
static class MyClass
{
   public const string NewLine="\n";
}

string x = "first line" + MyClass.NewLine + "second line"

3
-1: ระบบกำหนดไว้แล้วEnvironment.NewLine- ดูคำตอบอื่น ๆ
Richard

@ Richard: OP เท่าที่ฉันสามารถเข้าใจเขาต้องการที่จะใช้ตัวอักษรสตริง inlined เช่นconst string
abatishchev

@Richard Environment.NewLine เป็นแบบคงที่ไม่ใช่ const

1

เวอร์ชัน. net ที่ใหม่กว่าอนุญาตให้คุณใช้ $ ต่อหน้าตัวอักษรซึ่งอนุญาตให้คุณใช้ตัวแปรภายในดังนี้:

var x = $"Line 1{Environment.NewLine}Line 2{Environment.NewLine}Line 3";

1
บริบทเล็กน้อยจะไม่เลวร้าย
croxy

1
สิ่งนี้ไม่ได้ให้คำตอบสำหรับคำถาม เมื่อคุณมีเพียงพอชื่อเสียงคุณจะสามารถที่จะแสดงความคิดเห็นในโพสต์ใด ๆ ; แทนที่จะให้คำตอบที่ไม่จำเป็นต้องชี้แจงจากผู้ถาม - จากการรีวิว
H. Pauwelyn

@ H.Pauwelyn ツ: ขอบคุณสำหรับความคิดเห็น ฉันเพิ่มบริบทเล็กน้อย จากมุมมองของฉันทางออกแน่นอนตอบคำถาม
DanielK

0

หากคุณต้องการสตริง New Line เป็นค่าคงที่จริงๆคุณสามารถทำได้ดังนี้:

public readonly string myVar = Environment.NewLine;

ผู้ใช้ของคำหลักแบบอ่านอย่างเดียวใน C # หมายความว่าตัวแปรนี้สามารถกำหนดให้หนึ่งครั้งเท่านั้น คุณสามารถค้นหาเอกสารเกี่ยวกับมันนี่ อนุญาตให้ประกาศตัวแปรคงที่ซึ่งไม่ทราบค่าจนกว่าจะถึงเวลาดำเนินการ


0

ฉันชอบมากกว่า "ทาง pythonic"

List<string> lines = new List<string> {
    "line1",
    "line2",
    String.Format("{0} - {1} | {2}", 
        someVar,
        othervar, 
        thirdVar
    )
};

if(foo)
    lines.Add("line3");

return String.Join(Environment.NewLine, lines);

0

หากคุณทำงานกับเว็บแอปพลิเคชันคุณสามารถลองสิ่งนี้ได้

StringBuilder sb = new StringBuilder();
sb.AppendLine("Some text with line one");
sb.AppendLine("Some mpre text with line two");
MyLabel.Text = sb.ToString().Replace(Environment.NewLine, "<br />")

0

ถ้าผมเข้าใจคำถาม: คู่ที่จะได้รับการขึ้นบรรทัดใหม่ในด้านล่าง"\r\n" textboxตัวอย่างของฉันทำงาน -

   string s1 = comboBox1.Text;     // s1 is the variable assigned to box 1, etc.
   string s2 = comboBox2.Text;

   string both = s1 + "\r\n" + s2;
   textBox1.Text = both;

คำตอบทั่วไปอาจอยู่s1 s2 ในtext boxรูปแบบที่กำหนดไว้


-1

ที่นี่ Environment.NewLine ไม่ทำงาน

ฉันใส่ " < br / > " ในสตริงและทำงาน

Ex:

ltrYourLiteral.Text = "บรรทัดแรก <. br / > สายที่สอง.";

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.