开发者

.Net Removing all the first 0 of a string

开发者 https://www.devze.com 2023-01-02 04:56 出处:网络
I got the following : 01.05.03 I n开发者_开发技巧eed to convert that to 1.5.3 The problem is I cannot only trim the 0 because if I got :

I got the following :

01.05.03

I n开发者_开发技巧eed to convert that to 1.5.3

The problem is I cannot only trim the 0 because if I got :

01.05.10

I need to convert that to 1.5.10

So, what's the better way to solve that problem ? Regex ? If so, any regex example doing that ?


Expanding on the answer of @FrustratedWithFormsDesigner:

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


Regex-replace

(?<=^|\.)0+

with the empty string. The regex is:

(?<=     # 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

† note that not all regex flavors support variable-length look-behind, but .NET does.

If you expect this kind of input: "00.03.03" and want to to keep the leading zero in this case (like "0.3.3"), use this expression instead:

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

and again replace with the empty string.


From the comments (thanks Kobi): There is a more concise expression that does not require look-behind and is equivalent to my second suggestion:

\b0+(?=\d)

which is

\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

This works because the 0 happens to be a word character, so word boundaries can be used to find the first 0 in a row. It is a more compatible expression, because many regex flavors do not support variable-length look-behind, and some (like JavaScript) no look-behind at all.


You could split the string on ., then trim the leading 0s on the results of the split, then merge them back together.

I don't know of a way to do this in a single operation, but you could write a function that hides this and makes it look like a single operation. ;)

UPDATE:

I didn't even think of the other guy's regex. Yeah, that will probably do it in a single operation.


Here's another way you could do what FrustratedWithFormsDesigner suggests:

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

This is almost the same as dtb's answer, but doesn't require that the substrings be valid integers (it would also work with, e.g., "000A.007.0HHIMARK").

UPDATE: If you'd want any strings consisting of all 0s in the input string to be output as a single 0, you could use this:

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

Example input/output:

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


There's also the old-school way which probably has better performance characteristics than most other solutions mentioned. Something like:

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


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

Console.WriteLine(newS);

NOTE: You will have to thoroughly check for possible input combination.


This looks like it is a date format, if so I would use Date processing code

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

or even better

String newFormat = time.ToShortDateString();

which will respect you and your clients culture setting.

If this data is not a date then don't use this :)


I had a similar requirement to parse a string with street adresses, where some of the house numbers had leading zeroes and I needed to remove them while keeping the rest of the text intact, so I slightly edited the accepted answer to meet my requirements, maybe someone finds it useful. Basically doing the same as accepted answer, with the difference that I am checking if the string part can be parsed as an integer, and defaulting to the string value when 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);
}

Input: "Islands Brygge 34 B 07 TV"

Output: "Islands Brygge 34 B 7 TV"

0

精彩评论

暂无评论...
验证码 换一张
取 消