.NET จัดรูปแบบสตริงที่มีช่องว่างคงที่


199

ไม่. NET String.Format วิธีการอนุญาตให้วางตำแหน่งของสตริงที่ตำแหน่งคงที่ภายในสายอักขระความยาวคงที่

"สตริงไปที่นี่"
"สตริงไปที่นี่"
"สตริงไปที่นี่"

สิ่งนี้ทำได้โดยใช้. NET

แก้ไข - ฉันได้ลองฟอร์แมต / PadLeft / PadRight ไปสู่ความตาย พวกเขาไม่ทำงาน ฉันไม่รู้ว่าทำไม ฉันลงเอยด้วยการเขียนฟังก์ชั่นของตัวเองเพื่อทำสิ่งนี้

แก้ไข - ฉันทำผิดพลาดและใช้โคลอนแทนเครื่องหมายจุลภาคในตัวระบุรูปแบบ ควรเป็น "{0,20}"

ขอบคุณสำหรับคำตอบที่ยอดเยี่ยมและถูกต้องทั้งหมด


48
ฉันไม่เคยมีการจัดรูปแบบสตริงคำถามที่ฉันไม่สามารถตอบได้โดยไปที่หน้านี้: blog.stevex.net/index.php/string-formatting-in-csharp
jcollum

@jcollum: ฉันชอบที่จะขึ้นลงคะแนนคำตอบของคุณ แต่ไม่สามารถทำเพื่อแสดงความคิดเห็น
ดินาห์

PadLeft ใช้งานได้สำหรับฉันตรวจสอบว่าคุณกำลังออกจากพื้นที่ใน PadLeft (20, 'HERE GOES A SPACE')
Jedi Master Spooky

หมายความว่าอะไรโดย "ออกจากพื้นที่ใน" ถ้าคุณหมายถึง - ฉัน "ตัดแต่ง" สตริงแล้วไม่ใช่ มันยังไม่ทำงาน
user72491

คำตอบ:


473

สิ่งนี้จะให้สตริงที่คุณต้องการ:

string s = "String goes here";
string lineAlignedRight  = String.Format("{0,27}", s);
string lineAlignedCenter = String.Format("{0,-27}",
    String.Format("{0," + ((27 + s.Length) / 2).ToString() +  "}", s));
string lineAlignedLeft   = String.Format("{0,-27}", s);

64
สิ่งนี้ควรถูกทำเครื่องหมายเป็นคำตอบที่ถูกต้องสำหรับคำถาม แต่ดูเหมือนว่า OP ได้ออกจาก stackoverflow
Oliver

9
ถ้าคุณมองหาการตรวจสอบสีเขียวกับสูงสุดขึ้นเสียงคุณไม่ทราบวิธีการ SO;)
เดฟ Jellison

2
@DaveJellison ดูเหมือนว่าใครบางคนต้องเขียนปลั๊กอินเพื่อแก้ไขปัญหานั้นหรือดังนั้นเพียงแค่ทำให้มันเป็นความต้องการของผู้ใช้ที่กำหนดค่าได้
วอลเตอร์ Stabosz

1
@WalterStabosz ไม่สามารถเห็นด้วยเพิ่มเติม
Dave Jellison

2
เหตุใดจึงทำเช่นนี้,แทนที่จะใช้:ในการจัดรูปแบบอื่น ๆ ทั้งหมด usecases
LuckyLikey

65

ครั้งแรกและครั้งสุดท้ายอย่างน้อยเป็นไปได้โดยใช้ไวยากรณ์ต่อไปนี้:

String.Format("{0,20}", "String goes here");
String.Format("{0,-20}", "String goes here");

49

ในฐานะที่เป็น Visual Studio 2015 คุณสามารถทำเช่นนี้กับInterpolated Strings (เป็นกลวิธีคอมไพเลอร์ดังนั้นจึงไม่สำคัญว่าคุณจะกำหนดเป้าหมายเป็น. NET Framework รุ่นใด)

string value = "String goes here";
string txt1 = $"{value,20}";
string txt2 = $"{value,-20}";

9
คุณสมบัติ ac # 6
LuckyLikey

ฉันใช้ C # 6 มาหลายปีแล้วและไม่รู้มาก่อน! โหวตขึ้น :)
Avrohom Yisroel

17

คุณได้รับการแสดงและPadLeft นี้จะกรอกข้อมูลลงในที่ขาดหายไปPadRightPadCenter

public static class StringUtils
{
    public static string PadCenter(this string s, int width, char c)
    {
        if (s == null || width <= s.Length) return s;

        int padding = width - s.Length;
        return s.PadLeft(s.Length + padding / 2, c).PadRight(width, c);
    }
}

หมายเหตุถึงตนเอง: อย่าลืมอัปเดตประวัติส่วนตัวของคุณ: "วันหนึ่งฉันยังแก้ไขรหัสของ Joel Coehoorn!" ;-D -Serge


Joel ตัวอย่างที่ดี - ฉันพยายามใช้และไม่ได้อยู่ตรงกลางอย่างที่เป็นอยู่ ดูเหมือนว่าบรรทัดส่งคืนควรมีลักษณะดังนี้ (ฉันไม่มีตัวแทนมากพอที่จะแก้ไข ... ): return s.PadLeft ((padding / 2) + s.Length, c) .PadRight (width, c);
shaunmartin

11

ลองนี้:

"String goes here".PadLeft(20,' ');
"String goes here".PadRight(20,' ');

สำหรับศูนย์รับความยาวของสตริงและทำ padleft และ padright ด้วยอักขระที่จำเป็น

int len = "String goes here".Length;
int whites = len /2;
"String goes here".PadRight(len + whites,' ').PadLeft(len + whites,' ');

ดูเหมือนว่าการโทร String.Format () นั้นไม่จำเป็น
Joel Coehoorn

วิธีการของแพดนั้นดีเนื่องจากตัวเลือกรูปแบบต้องการความยาวที่คงที่ (นั่นคือString.Format("{0,-length}", something)จะไม่คอมไพล์
Roberto

6

ขอบคุณสำหรับการอภิปรายวิธีนี้ใช้งานได้ (VB):

Public Function StringCentering(ByVal s As String, ByVal desiredLength As Integer) As String
    If s.Length >= desiredLength Then Return s
    Dim firstpad As Integer = (s.Length + desiredLength) / 2
    Return s.PadLeft(firstpad).PadRight(desiredLength)
End Function
  1. StringCentering ()รับค่าอินพุตสองค่าและส่งคืนสตริงที่จัดรูปแบบ
  2. เมื่อความยาวของsมากกว่าหรือเท่ากับdeisredLengthฟังก์ชันจะส่งคืนสตริงเดิม
  3. เมื่อความยาวของsมีขนาดเล็กกว่าที่ต้องการความยาวจะมีเบาะทั้งสองด้าน
  4. เนื่องจากการเว้นวรรคตัวอักษรเป็นจำนวนเต็มและไม่มีที่ว่างครึ่งหนึ่งเราสามารถแบ่งพื้นที่ไม่เท่ากัน ในการดำเนินการนี้การแยกยิ่งใหญ่ไปยังส่วนท้ายสุด
  5. ฟังก์ชั่นต้อง .NET Framework เนื่องจากPadLeft ()และPadRight ()
  6. ในบรรทัดสุดท้ายของฟังก์ชั่นที่จะมีผลผูกพันจากซ้ายไปขวาเพื่อfirstpadถูกนำไปใช้ตามด้วยdesiredLengthแผ่น

นี่คือรุ่น C #:

public string StringCentering(string s, int desiredLength)
{
    if (s.Length >= desiredLength) return s;
    int firstpad = (s.Length + desiredLength) / 2;
    return s.PadLeft(firstpad).PadRight(desiredLength);
}

เพื่อช่วยในการทำความเข้าใจจะใช้แป้นตัวเลขแบบตัวแปรตัวแรก s.PadLeft (แผ่นแรก)ใช้กับช่องว่างสีขาวนำหน้า (จำนวนที่ถูกต้อง) PadRight ที่เหมาะสมที่สุด(ที่ต้องการความยาว)มีการผูกที่ต่ำกว่าเสร็จสิ้นโดยการใช้ช่องว่างสีขาวต่อท้าย


1
ยินดีต้อนรับสู่ SO, ไค นี่เป็นอีกตัวอย่างหนึ่งของการโพสต์และคำตอบแรกที่ยอดเยี่ยม +1
Brian

ขอบคุณ Brian คำถามดั้งเดิมที่ด้านบนของโพสต์นี้เป็นจุดเริ่มต้นที่ยอดเยี่ยม ฉันได้แรงบันดาลใจจากการโพสต์และคำตอบก่อนหน้านี้ทั้งหมดของฉัน
Chi

1

นี่คือรุ่น VB.NET ที่ฉันสร้างขึ้นโดยได้แรงบันดาลใจจากคำตอบของ Joel Coehoorn การแก้ไขของ Oliver และความคิดเห็นของ shaunmartin:

    <Extension()>
Public Function PadCenter(ByVal [string] As String, ByVal width As Integer, ByVal c As Char) As String

    If [string] Is Nothing Then [string] = String.Empty
    If (width <= [string].Length) Then Return [string]

    Dim padding = width - [string].Length
    Return [string].PadLeft([string].Length + (padding \ 2), c).PadRight(width, c)

End Function

<Extension()>
Public Function PadCenter(ByVal [string] As String, ByVal width As Integer) As String

    If [string] Is Nothing Then [string] = String.Empty
    If (width <= [string].Length) Then Return [string]

    Dim padding = width - [string].Length
    Return [string].PadLeft([string].Length + (padding \ 2)).PadRight(width)

End Function

นี่คือการตั้งค่าเป็นส่วนขยายของสตริงภายในโมดูลสาธารณะ (วิธีที่คุณทำส่วนขยายใน VB.NET ซึ่งแตกต่างจาก C # เล็กน้อย) การเปลี่ยนแปลงเล็กน้อยของฉันคือมันปฏิบัติต่อสตริงว่างเปล่าเป็นสตริงว่างและมันรองสตริงว่างเปล่าที่มีค่าความกว้าง (ตรงตามความต้องการเฉพาะของฉัน) หวังว่านี่จะแปลงเป็น C # ได้อย่างง่ายดายสำหรับทุกคนที่ต้องการมัน หากมีวิธีที่ดีกว่าในการอ้างอิงคำตอบการแก้ไขและความคิดเห็นที่ฉันพูดถึงข้างต้นซึ่งเป็นแรงบันดาลใจให้กับโพสต์ของฉันโปรดแจ้งให้ฉันทราบและฉันจะทำ - ฉันค่อนข้างใหม่ในการโพสต์ แสดงความคิดเห็น (อาจมีตัวแทนไม่เพียงพอ)


0

ฉันโพสต์บทความ CodeProject ที่อาจเป็นสิ่งที่คุณต้องการ

โปรดดู: วิธี AC # สำหรับการจัดรูปแบบความกว้างและสไตล์ทางอ้อม

โดยทั่วไปมันเป็นวิธีการ FormatEx ที่ทำหน้าที่เหมือน String.Format ยกเว้นจะอนุญาตให้ปรับเปลี่ยนการจัดตำแหน่งเป็นศูนย์กลาง

FormatEx("{0,c10}", value);

หมายถึงกึ่งกลางค่าของ varArgs [0] ในฟิลด์กว้าง 10 ตัวอักษรเอียงขวาถ้าต้องการพื้นที่ว่างภายในเพิ่มเติม

FormatEx("{0,c-10}", value);

หมายถึงกึ่งกลางค่าของ varArgs [0] ในฟิลด์กว้าง 10 ตัวอักษรยันซ้ายถ้าต้องการพื้นที่ว่างภายในเพิ่มเติม

แก้ไข: ภายในเป็นการรวมกันของ PadCenter ของ Joel กับการแยกวิเคราะห์บางอย่างเพื่อปรับโครงสร้างรูปแบบและ varArgs สำหรับการเรียกไปยัง String.Format ที่ทำสิ่งที่คุณต้องการ

-Jesse


-1

ดูเหมือนว่าคุณต้องการสิ่งนี้สิ่งที่จะทำให้คุณสตริงที่จุดคงที่ในสตริงความยาวคงที่:

Dim totallength As Integer = 100
Dim leftbuffer as Integer = 5
Dim mystring As String = "string goes here"
Dim Formatted_String as String = mystring.PadLeft(leftbuffer + mystring.Length, "-") + String.Empty.PadRight(totallength - (mystring.Length + leftbuffer), "-")

โปรดทราบว่าสิ่งนี้จะมีปัญหาหาก mystring.length + leftbuffer เกินความยาวทั้งหมด


-7
/// <summary>
/// Returns a string With count chars Left or Right value
/// </summary>
/// <param name="val"></param>
/// <param name="count"></param>
/// <param name="space"></param>
/// <param name="right"></param>
/// <returns></returns>
 public static string Formating(object val, int count, char space = ' ', bool right = false)
{
    var value = val.ToString();
    for (int i = 0; i < count - value.Length; i++) value = right ? value + space : space + value;
    return value;
}

3
อย่าใช้รหัสนี้ - มันสร้างการจัดสรรสตริงที่ไม่จำเป็นจำนวนมาก ใช้ตัวระบุรูปแบบ builtin และวิธีการ padding แทน
Oskar Berggren

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