2010-05-20 6 views
5

У меня очень простой вопрос, и я не должен его повесить, но я. Ха-ха!Каков наиболее эффективный способ форматирования следующей строки?

У меня есть строка, что я получаю в следующем формате (ы):

123456-D53

123455-4D

234234-4

Желаемый результат, форматирование сообщения, составляет:

123-455-444

123-455-55

123-455-5

или

123-455

Формат, в конечном счете, зависит от общее количество символов в исходной строке.

Я видел RAL идеи, как это сделать, но я продолжаю дело, что есть лучший способ, чем string.replace и сцепить ...

спасибо за предложения ..

Ян

+6

Вы уверены, что эффективность является наиболее важным показателем здесь, а не, например, читаемость? Профилированы ли вы, чтобы убедиться, что это узкое место в вашей программе? –

+1

Нет на обоих счетах. На самом деле, я уверен, что это не узкое место, и эффективность не является самой важной метрикой. Мне просто любопытно, и я думал об этом весь день. :) –

ответ

2

Я предполагаю, что это не просто полагается на входы, всегда являющиеся числовыми? Если это так, я имею в виду что-то вроде этого

private string ApplyCustomFormat(string input) 
{ 
    StringBuilder builder = new StringBuilder(input.Replace("-", "")); 

    int index = 3; 
    while (index < builder.Length) 
    { 
     builder.Insert(index, "-"); 
     index += 4; 
    } 
    return builder.ToString(); 
} 
+0

Это похоже на мою реализацию. Я просто догнал «это самый эффективный способ сделать это?». вопрос .. –

+0

@Ian P - «самый эффективный» менее важен, чем «достаточно эффективен». См. Первый комментарий. У меня возникнет соблазн написать «менее эффективный» код, который использует IEnumerable chunker (метод или Regex) и String.Join ;-) – 2010-05-20 18:18:41

+0

Выбрал этот ответ в качестве ответа, поскольку он работал сначала в спецификации, которую я описываю. Хотя, другие плакаты обновили свой код для работы по мере необходимости. Все достойны зеленых галочек, но я могу только дать один :) –

2

EDIT: для Просмотреть историю старых версий.
Вы можете использовать char.IsDigit() только для поиска цифр.

var output = new StringBuilder(); 
var digitCount = 0; 

foreach(var c in input) 
{ 
    if(char.IsDigit(c)) 
    { 
    output.Append(c); 
    digitCount++; 
    if(digitCount % 3 == 0) 
    { 
     output.Append("-"); 
    } 
    } 
} 

// Remove possible last - 
return output.ToString().TrimEnd('-'); 

Этот код должен заполнить слева направо (теперь я получил его, первое чтение, то код) ...
К сожалению, я до сих пор не могу проверить это прямо сейчас.

+0

Я собираюсь уточнить свой исходный пост, строка может быть буквенно-цифровой, а не только цифровой. –

+0

Я думаю, что это заполняет цифры в неправильном направлении. Он так хочет, чтобы он был оговорен. – user7116

+0

@Ian: Я использую char.IsDigit, сейчас. @sixlettervariables: вы правы, что делает его намного сложнее. – tanascius

4

Tanascius правильно, но я не могу комментировать или upvote из-за моего отсутствия репутации, но если вы хотите получить дополнительную информацию о String.Format Ive нашел, что это полезно. http://blog.stevex.net/string-formatting-in-csharp/

+0

Отличная ссылка, спасибо. –

+0

Я должен был сообщить вам, что я удалил свой ответ :-). ОП изменил вопрос, и он больше не применяется. Кроме того, sixlettervariable указал, что на самом деле он не отвечает и на исходный вопрос. – 2010-05-20 18:30:12

0

Не самый быстрый, но просто на глазах (изд: читать):

string Normalize(string value) 
{ 
    if (String.IsNullOrEmpty(value)) return value; 

    int appended = 0; 
    var builder = new StringBuilder(value.Length + value.Length/3); 
    for (int ii = 0; ii < value.Length; ++ii) 
    { 
     if (Char.IsLetterOrDigit(value[ii])) 
     { 
      builder.Append(value[ii]); 
      if ((++appended % 3) == 0) builder.Append('-'); 
     } 
    } 

    return builder.ToString().TrimEnd('-'); 
} 

Использует догадку, чтобы предварительно выделить длину StringBuilder «s. Это будет принимать любой буквенно-цифровой ввод с любым количеством нежелательных сообщений, добавляемых пользователем, включая избыточные пробелы.

+6

Ха-ха, у нас должны быть разные типы глаз: p – 2010-05-20 18:21:03

+0

Вы должны проверить '(ii + 1)% 3 == 0'. –

+0

@ 0xA3: хороший улов. @pst: если я вернусь, чтобы прочитать это, будет очевидно, что происходит. Нет obfuscation;) – user7116

2

Вот метод, который использует комбинацию регулярных выражений и LINQ для извлечения групп из трех букв за раз, а затем объединяет их снова. Примечание: предполагается, что вход уже проверен.Проверка также может быть выполнена с помощью регулярного выражения.

string s = "123456-D53"; 
string[] groups = Regex.Matches(s, @"\w{1,3}") 
         .Cast<Match>() 
         .Select(match => match.Value) 
         .ToArray(); 
string result = string.Join("-", groups); 

Результат:

 
123-456-D53 
Смежные вопросы