.Net Удаление всех первых 0 строк - PullRequest
7 голосов
/ 02 июня 2010

Я получил следующее:

01.05.03

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

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

01.05.10

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

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

Ответы [ 8 ]

16 голосов
/ 02 июня 2010

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

string Strip0s(string s)
{
    return string.Join<int>(".", from x in s.Split('.') select int.Parse(x));
}
15 голосов
/ 02 июня 2010

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) вообще не поддерживают.

3 голосов
/ 02 июня 2010

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

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

UPDATE:

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

1 голос
/ 02 июня 2010

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

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();
}
1 голос
/ 02 июня 2010

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

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

Это почти то же самое, что и ответ dtb, но не требует, чтобы подстроки были действительными целыми числами (это также будет работать, например, с "000A.007.0HHIMARK").

ОБНОВЛЕНИЕ : Если вы хотите, чтобы любые строки, состоящие из всех 0 во входной строке, выводились как один 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 голосов
/ 18 августа 2014

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

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

Ввод: «Острова Брюгге 34 B 07 ТВ»

Вывод: "Острова Брюгге 34 B 7 ТВ"

0 голосов
/ 02 июня 2010

Похоже, что это формат даты, в таком случае я бы использовал код обработки даты

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

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

String newFormat = time.ToShortDateString();

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

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

0 голосов
/ 02 июня 2010
string s = "01.05.10";
string newS = s.Replace(".0", ".");
newS = newS.StartsWith("0") ? newS.Substring(1, newS.Length - 1) : newS;

Console.WriteLine(newS);

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...