.NET Форматирование строки с фиксированными пробелами

199

Позволяет ли метод .NET String.Format размещать строку в фиксированной позиции в пределах строки фиксированной длины.

"Строка идет сюда"
"Строка идет сюда"
"Строка идет сюда"

Как это сделать с помощью .NET?

Редактировать - я пробовал Format / PadLeft / PadRight до смерти. Они не работают. Я не знаю почему. Я написал свою собственную функцию для этого.

Редактировать - я допустил ошибку и использовал двоеточие вместо запятой в спецификаторе формата. Должно быть "{0,20}".

Спасибо за все отличные и правильные ответы.

user72491
источник
48
У меня никогда не было вопроса о форматировании строки, на который я не смог бы ответить, зайдя на эту страницу: blog.stevex.net/index.php/string-formatting-in-csharp
jcollum
@jcollum: я бы с удовольствием проголосовал за твой ответ, но никто не может сделать комментарии
Дина
PadLeft работает для меня, чтобы убедиться, что вы покидаете пространство в PadLeft (20, «ЗДЕСЬ ПРОСТРАНСТВУЕТ»)
Мастер-джедай 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);
Guffa
источник
64
Это должно быть помечено как правильный ответ на вопрос, но похоже, что OP покинул стекопоток.
Оливер
9
Если вы ищете зеленый чек против самых высоких голосов, вы не знаете, как ТАК;)
Дейв Джеллисон
2
@DaveJellison Похоже, кто-то должен написать плагин, чтобы исправить это, или SO должен просто сделать его настраиваемым пользовательским предпочтением.
Вальтер Стабош
1
@WalterStabosz не может согласиться больше.
Дэйв
2
почему это делается ,вместо того, :как во всех других случаях использования форматирования?
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}";
Sprotty
источник
9
его функция AC # 6.
LuckyLikey
Я использую C # 6 в течение многих лет и не знал этого! Проголосовал :)
Аврохом Исроэль
17

Вы были показаны PadLeftи PadRight. Это заполнит недостающее PadCenter.

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);
    }
}

Примечание для себя: не забудьте обновить свое резюме: «Однажды я даже исправил код Джоэла Кехорна!» ;-D -Serge

Джоэл Коухорн
источник
Джоэл, хороший фрагмент - я пытаюсь использовать его, и он не совсем в центре, так оно и есть. Похоже, что возвращаемая строка должна выглядеть примерно так (мне не хватает rep для редактирования ...): 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 () излишни.
Джоэл Коухорн
Методы pad хороши, так как параметры формата требуют, чтобы длины были константами (то есть String.Format("{0,-length}", something)не компилируются.
Роберто
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);
}

Чтобы помочь пониманию, используется целочисленная переменная firstpad . s.PadLeft (firstpad) применяет (правильное количество) первые пробелы. Крайний правый PadRight (requiredLength) имеет нижнюю привязку, заканчивающуюся применением конечных пробелов.

чи
источник
1
Добро пожаловать на Чи. Это еще один пример БОЛЬШОГО первого поста и ответа. +1
Брайан
Спасибо Брайан, оригинальный вопрос в начале этого поста является отличной отправной точкой. Меня вдохновляют все посты и ответы, предшествующие моим.
Чи
1

Вот версия VB.NET, которую я создал, вдохновленный ответом Джоэла Кехорна, правкой Оливера и комментарием Шонмартина:

    <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 # way для косвенного форматирования ширины и стиля.

По сути, это метод FormatEx, который действует как String.Format, за исключением того, что он допускает модификатор центрированного выравнивания.

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

Означает центрирование значения varArgs [0] в поле шириной 10 символов, наклоняется вправо, если требуется дополнительное пространство для заполнения.

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

Означает центрирование значения varArgs [0] в поле шириной 10 символов, наклон влево, если требуется дополнительное пространство для заполнения.

Редактировать: Внутренне, это комбинация PadCenter Джоэла с некоторым анализом для реструктуризации формата и 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 превышает totallength

Атилио Джобсон
источник
-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;
}
Paulos02
источник
3
Не используйте этот код - он генерирует много ненужных выделений строк. Вместо этого используйте встроенные спецификаторы формата и методы заполнения.
Оскар Берггрен
1
святой ... представьте себе, как использовать это внутри цикла :)
LuckyLikey