2010-06-02 2 views
7

я получил следующее:.Net Удаление всех первых 0 строки

01.05.03

Мне нужно преобразовать, что в 1.5.3

Проблема в том, что я могу не только обрезать 0, потому что если я получил:

01.05.10

Мне нужно преобразовать, что в 1.5.10

Итак, каков лучший способ решить эту проблему? Regex? Если да, то какой-нибудь пример регулярного выражения?

+0

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

+2

Нет, это не дата, это уровень иерархии – Melursus

ответ

16

Расширяя ответа @FrustratedWithFormsDesigner:

string Strip0s(string s) 
{ 
    return string.Join<int>(".", from x in s.Split('.') select int.Parse(x)); 
} 
+1

+1 для Linq-ifying it! Я все время забываю, что можно так поступить. – FrustratedWithFormsDesigner

+1

+1 хорошая альтернатива, хотя она не имеет дело с '' 00.03.03 "' (что может или не может произойти). – Tomalak

+0

@ Томалак: это хороший момент. Позвольте мне исправить это :-) – dtb

3

Вы можете использовать split строку на ., затем обрезать ведущие 0 по результатам раскола, а затем объединить их вместе.

Я не знаю, как это сделать за одну операцию, но вы можете написать функцию, которая скрывает это, и делает это выглядит как как отдельная операция. ;)

UPDATE:

Я даже не думать о регулярных выражений другого парня. Да, это, вероятно, сделает это за одну операцию.

+0

+1 для удобства чтения результирующего кода, а не регулярное выражение, которое потребует комментариев –

+0

+1 Я предпочел бы это для решения регулярных выражений. – dtb

+0

@Miki Watts: Реальное решение не требует других комментариев, кроме варианта split/loop/join: '/ * удалять ведущие нули на номер сборки * /'. – Tomalak

15

Regex замены

(?<=^|\.)0+ 

с пустой строкой. Регулярное выражение:

 
(?<=  # begin positive look-behind (i.e. "a position preceded by") 
    ^|\. # the start of the string or a literal dot † 
)  # end positive look-behind 
0+  # one or more "0" characters 

† Заметим, что не все регулярные выражения вкусов поддержки переменной длины Двойник позади, но .NET делает.

Если вы ожидаете этот вид ввода: "00.03.03" и хотите сохранить лидирующие нули в этом случае (как "0.3.3"), использовать это выражение вместо:

(?<=^|\.)0+(?=\d) 

и снова заменить на пустую строку.


Из комментариев (спасибо Коби): Существует более краткое выражение, которое не требует Двойник позади и эквивалентна моему второму предложению:

\b0+(?=\d) 

которая

 
\b  # a word boundary (a position between a word char and a non-word char) 
0+  # one or more "0" characters 
(?=\d) # positive look-ahead: a position that's followed by a digit 

Это работает, потому что 0 является символом слова, поэтому границы слов можно использовать для поиска первого 0 в строке. Это более совместимое выражение, потому что многие ароматы регулярных выражений не поддерживают внешний вид переменной длины, а некоторые (например, JavaScript) вообще не выглядят.

+0

Можете ли вы привести мне пример кода C#, который делает это с заменой, пожалуйста? – Melursus

+4

@Melursus: Нет, потому что это очень легко найти. Официальная документация и несанкционированные веб-сайты (в том числе и Stack Overflow) могут дать вам пример использования регулярных выражений в .NET. – Tomalak

+1

'\ b0 + (? = \ D)' также будет хорошо работать здесь и сохранить один ноль. – Kobi

0
string s = "01.05.10"; 
string newS = s.Replace(".0", "."); 
newS = newS.StartsWith("0") ? newS.Substring(1, newS.Length - 1) : newS; 

Console.WriteLine(newS); 

ПРИМЕЧАНИЕ. Вам необходимо будет тщательно проверить возможную комбинацию ввода.

+1

Возможно, это не сработает, если у него '001.00005.10', но он не уточнил, возможно ли это. – FrustratedWithFormsDesigner

1

Вот еще один способ, которым Вы могли бы сделать то, что FrustratedWithFormsDesigner предлагает:

string s = "01.05.10"; 
string s2 = string.Join(
    ".", 
    s.Split('.') 
     .Select(str => str.TrimStart('0')) 
     .ToArray() 
); 

Это почти же, как ответ DTB, но Безразлично» t требуют, чтобы подстроки были действительными целыми числами (он также работал бы, например, «000A.007.0HHIMARK»).

UPDATE: Если вы хотели бы все строки, состоящие из всех 0s во входной строке, который будет выводиться в виде одного 0, вы могли бы использовать это:

string s2 = string.Join(
    ".", 
    s.Split('.') 
     .Select(str => TrimLeadingZeros(str)) 
     .ToArray() 
); 

public static string TrimLeadingZeros(string text) { 
    int number; 
    if (int.TryParse(text, out number)) 
     return number.ToString(); 
    else 
     return text.TrimStart('0'); 
} 

Пример ввода/вывода:

00.00.000A.007.0HHIMARK // input 
0.0.A.7.HHIMARK   // output 
+0

Это решение, которое у меня было до того, как я изменил его на 'int.Parse'. Он терпит неудачу, когда часть полностью состоит из символов «0», например, «03.00.10». – dtb

+0

@dtb: Что вы подразумеваете под словом «fail»? Я не вижу, где ОП указывает, что должно произойти в этом случае. Если конечные нули должны быть удалены, я бы подумал, что вывод «03.00.10» должен быть «03..10», что и есть. В противном случае OP должен будет предоставить несколько более подробные требования (если только я не упустил что-то). –

0

Это выглядит как это формат даты, если это так, я хотел бы использовать дата код обработки

DateTime time = DateTime.Parse("01.02.03"); 
String newFormat = time.ToString("d.M.yy"); 

или даже лучше

String newFormat = time.ToShortDateString(); 

, который будет уважать вас и ваши настройки клиентов культуры.

Если эти данные не дата, то не использовать это :)

+0

OP заявил, что это не дата. – dtb

+0

жаль пропустил комментарий. по ОП –

1

Там также старая школа путь, который, вероятно, имеет лучшие характеристики по сравнению с большинством других решений, упомянутых. Что-то вроде:

static public string NormalizeVersionString(string versionString) 
{ 
    if(versionString == null) 
     throw new NullArgumentException("versionString"); 

    bool insideNumber = false;  
    StringBuilder sb = new StringBuilder(versionString.Length); 
    foreach(char c in versionString) 
    { 
     if(c == '.') 
     { 
      sb.Append('.'); 
      insideNumber = false; 
     } 
     else if(c >= '1' && c <= '9') 
     { 
      sb.Append(c); 
      insideNumber = true; 
     } 
     else if(c == '0') 
     { 
      if(insideNumber) 
       sb.Append('0'); 
     } 
    } 
    return sb.ToString(); 
} 
0

У меня было подобное требование, чтобы разобрать строку с уличными адресами, где ведущие некоторые из номеров домов нули, и мне нужно, чтобы удалить их, сохраняя при этом остальной текст без изменений, так что я немного отредактировал принятый ответ для удовлетворения моих требований, может быть, кто-то сочтет это полезным. В основном, делая то же самое, что и принятый ответ, с той разницей, что я проверяю, может ли строка быть разобрана как целое число, и по умолчанию для строкового значения false;

string Strip0s(string s) 
{ 
    int outputValue; 
    return 
     string.Join(" ", 
      from x in s.Split(new[] { ' ' }) 
      select int.TryParse(x, out outputValue) ? outputValue.ToString() : x); 
} 

Входной сигнал: "острова Brygge 34 B 07 TV"

Выход: "острова Brygge 34 B 7 ТВ"

Смежные вопросы