16

I have a compressed string value I'm extracting from an import file. I need to format this into a parcel number, which is formatted as follows: ##-##-##-###-###. So therefore, the string "410151000640" should become "41-01-51-000-640". I can do this with the following code:

String.Format("{0:##-##-##-###-###}", Convert.ToInt64("410151000640"));

However, The string may not be all numbers; it could have a letter or two in there, and thus the conversion to the int will fail. Is there a way to do this on a string so every character, regardless of if it is a number or letter, will fit into the format correctly?

6 Answers 6

39
Regex.Replace("410151000640", @"^(.{2})(.{2})(.{2})(.{3})(.{3})$", "$1-$2-$3-$4-$5");

Or the slightly shorter version

Regex.Replace("410151000640", @"^(..)(..)(..)(...)(...)$", "$1-$2-$3-$4-$5");
Sign up to request clarification or add additional context in comments.

4 Comments

Works like a charm! I extracted this into a wrapper method with some validation and error handling. Thanks!
I must really learn Regex properly myself. A very good solution to this problem.
@Øyvind If it helps, I like to use regular-expressions.info/tutorial.html for reference. They also talk about the different flavors of regex provided by different engines.
Thanks. I'll read up on RegExp there. Looks like a good source of information.
12

I would approach this by having your own formatting method, as long as you know that the "Parcel Number" always conforms to a specific rule.

public static string FormatParcelNumber(string input)
{
  if(input.length != 12)
     throw new FormatException("Invalid parcel number. Must be 12 characters");

  return String.Format("{0}-{1}-{2}-{3}-{4}",
                input.Substring(0,2),
                input.Substring(2,2),
                input.Substring(4,2), 
                input.Substring(6,3), 
                input.Substring(9,3));
}

1 Comment

This works nicely. So it really comes down to whether to use regular expressions (of which I'm not an expert) or not.
3

This should work in your case:

string value = "410151000640";
for( int i = 2; i < value.Length; i+=3){
  value = value.Insert( i, "-");
}

Now value contains the string with dashes inserted.

EDIT

I just now saw that you didn't have dashes between every second number all the way, to this will require a small tweak (and makes it a bit more clumsy also I'm afraid)

string value = "410151000640";
for( int i = 2; i < value.Length-1; i+=3){
  if( value.Count( c => c == '-') >= 3) i++;
  value = value.Insert( i, "-");
}

Comments

3

If its part of UI you can use MaskedTextProvider in System.ComponentModel

    MaskedTextProvider prov = new MaskedTextProvider("aa-aa-aa-aaa-aaa");
    prov.Set("41x151000a40");
    string result = prov.ToDisplayString();

1 Comment

Shouldn't the 'a' in your mask be '&'? 'a' is Alphanumeric, optional. The only characters it will accept are the ASCII letters a-z and A-Z. msdn.microsoft.com/en-us/library/…
1

Here is a simple extension method with some utility:

    public static string WithMask(this string s, string mask)
    {
        var slen = Math.Min(s.Length, mask.Length);
        var charArray = new char[mask.Length];
        var sPos = s.Length - 1;
        for (var i = mask.Length - 1; i >= 0 && sPos >= 0;)
            if (mask[i] == '#') charArray[i--] = s[sPos--];
            else
                charArray[i] = mask[i--];
        return new string(charArray);
    }

Use it as follows:

        var s = "276000017812008";
        var mask = "###-##-##-##-###-###";
        var dashedS = s.WithMask(mask);

You can use it with any string and any character other than # in the mask will be inserted. The mask will work from right to left. You can tweak it to go the other way if you want.

Have fun.

Comments

0

If i understodd you correctly youre looking for a function that removes all letters from a string, aren't you?

I have created this on the fly, maybe you can convert it into c# if it's what you're looking for:

Dim str As String = "410151000vb640"
str = String.Format("{0:##-##-##-###-###}", Convert.ToInt64(MakeNumber(str)))


Public Function MakeNumber(ByVal stringInt As String) As String
    Dim sb As New System.Text.StringBuilder
    For i As Int32 = 0 To stringInt.Length - 1
        If Char.IsDigit(stringInt(i)) Then
            sb.Append(stringInt(i))
        End If
    Next
    Return sb.ToString
End Function

1 Comment

No, the letters also are included in the parcel number, for instance "410151000vb6" should become "41-01-51-000-vb6"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.