4

Edit:

Because of your responses I think I've asked the question wrong.

It's not that my solution doesn't work or isn't very clean. I'm interested if there is a general way, how you can foramt a string. Like you can do it with a int or other data types.

So I couldn't find one. But I hope there is one.

So that's the question I wanted to ask:

Does C# provides a way to format strings, like it does for a int or other data types?

I'm looking for something like this:

myString.Format(myFormat);

or:

myFormattedString = String.Format(myString, myFormat);

And if the answer is no, it's also ok. I just want to know it. (And maybe someone else as well)



Original question:

What's the best way to change the format of a string?

So I have a string that looks like this:

"123456789012345678"

And now I want that:

"12.34.567890.12345678"

I'm using this, but I don't find it very clean:

private string FormatString(string myString)
{
    return myString.Insert(2, ".").Insert(5, ".").Insert(12, ".");
}

Things I've tried:

// Too long.
private string FormatString(string myString)
{
    return myString.Substring(0, 2)
         + "."
         + myString.Substring(2, 2)
         + "."
         + myString.Substring(4, 6)
         + "."
         + myString.Substring(10, 8);
}

// Convertion from string -> long -> string.
private string FormatString(string myString)
{
    return String.Format("{0:##'.'##'.'######'.'########}", long.Parse(myString));
}

I'm looking for something like that:

private string FormatString(string myString)
{
    return String.Format("{0:##'.'##'.'######'.'########}", myString);
}
la.urin
  • 41
  • 2
  • 6
  • 6
    "I'm using this, but I don't find it very clean:" I think it´s **very** clear as it´s easy to understand. – MakePeaceGreatAgain Mar 08 '17 at 09:58
  • Was just typing the same thing as HimBromBeere. This to me is very explicit what is going on. I'd keep it!! – Dave Becker Mar 08 '17 at 09:59
  • Keep what you have. It's really clean. – mindOfAi Mar 08 '17 at 10:01
  • Have you tried c#6 interpolated strings to have something like what you want but mildly shorter http://stackoverflow.com/questions/37113595/c-sharp-6-how-to-format-double-using-interpolated-string – AnonyMouse Mar 08 '17 at 10:01
  • You can write a method which accept array of parameters (see [params](http://stackoverflow.com/q/7580277/1997232)), where you specify insert points for dots relative to original string. Then you don't need to look into this code anymore, just test it once. I also find it not very clean what you have to specify positions incremented depending on how many insertations occured already. – Sinatr Mar 08 '17 at 10:02
  • Hmm, then I perhaps asked the question wrong.I try again: Is there a way to lay a format over a string in general way? – la.urin Mar 08 '17 at 10:03
  • 2
    Possible duplicate of [string.insert multiple values. Is this possible?](http://stackoverflow.com/questions/9484509/string-insert-multiple-values-is-this-possible) – Sinatr Mar 08 '17 at 10:13
  • 1
    I would invert the order of `Insert`: `myString.Insert(10, ".").Insert(4, ".").Insert(2, ".")`. In this way it is more clear what is the initial position where you are inserting the `"."`... In the way you wrote the code, the second `Insert()` had to count the already-inserted first `"."` – xanatos Mar 08 '17 at 10:25
  • @xanatos Yes that makes sense, thank you. – la.urin Mar 08 '17 at 10:28
  • See if my answer is near of what you wanted – Pikoh Mar 08 '17 at 10:32

3 Answers3

4

I don't see anything wrong with your code, but if you want a better matching system, you might want to consider regular expressions:

(\d{2})(\d{2})(\d{6})(\d{8})

And replace it with:

$1\.$2\.$3\.$4

(In action)

But my two cents: keep it like it is.

Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
  • 1
    I'd +2 that link to regex101 if I could..... how come I never about that site? It looks awesome. – Dave Becker Mar 08 '17 at 10:10
  • 2
    This reminds me of a quote by [Jamie Zawinski](https://en.wikipedia.org/wiki/Jamie_Zawinski): _Some people, when confronted with a problem, think "I know, I'll use regular expressions." Now they have two problems._ scnr ;) – Rabban Mar 08 '17 at 10:36
  • Chuckle, I know what you mean! I like to think of myself as Regex expert, but never for longer than a day :) – Dave Becker Mar 08 '17 at 10:59
1

Well...when the framework does not provide what you want, you can always do it yourself.

I've made this method as a experiment. It can surely be optimized and is not fully tested, but it can give you a view of what you could do:

private string FormatString(string myString,string format)
{
    const char number = '#';
    const char character = '%';
    StringBuilder sb = new StringBuilder();

    if (format.Length < myString.Length) throw new Exception("Invalid format string");

    int i = 0;
    foreach (char c in format)
    {
        switch (c)
        {
            case number:
                if (char.IsDigit(myString[i]))
                {
                    sb.Append(myString[i]);
                    i++;
                }
                else
                {
                    throw new Exception("Format string doesn't match input string");
                }
                break;
            case character:
                if (!char.IsDigit(myString[i]))
                {
                    sb.Append(myString[i]);
                    i++;
                }
                else
                {
                    throw new Exception("Format string doesn't match input string");
                }
                break;
            default:
                sb.Append(c);
                break;
        }

    }
    return sb.ToString();
}

This method expects the format string to have either a # to denote digit, a % to denote a character, or any other character that would be copied literally to the formatted string.

Usage:

string test = FormatString("123456789012345678", "##.##.######.########");
//outputs 12.34.567890.12345678
string test = FormatString("12345F789012345678", "##.##.#%####.########");
//outputs 12.34.5F7890.12345678
Pikoh
  • 7,582
  • 28
  • 53
  • yeah, this would work, but you know, i'm really lazy... :) But if I interpret your answer correctly, the framework doesn't support a format for a string. That would be really sad. Before c# I worked with Pl/1, where you have this: [link](https://www.ibm.com/support/knowledgecenter/en/SSY2VQ_2.0.0/com.ibm.aix.pli.doc/picchar.htm#picchar) – la.urin Mar 08 '17 at 12:01
  • Well i barely remember Cobol also having something similar. I don't think C# has something like this, that btw is a way of validating strings, not a way to format them.Using this method you have something to format and validate the strings. And it's already done, so even being lazy you could use it :) – Pikoh Mar 08 '17 at 12:16
  • No it's not only validating. But the reference is a bit shitty. You can see it better hier: [link](https://www.ibm.com/support/knowledgecenter/en/SSY2VQ_2.0.0/com.ibm.aix.pli.doc/inschar.htm#inschar). For alphabetic values it's the same. But I think I'll use my variant with the insert. The next guy who has to understand or change my code, will be grateful. Thank you for your effort, perhaps it helps someone else, who needs formatting and validating. – la.urin Mar 08 '17 at 13:05
0

If your string will always be a number then you can do it like this:

string stringData = "123456789012345678";
string dataInFormat = Convert.ToInt64(stringData).ToString(@"##\.##\.######\.########");

First convert string to long and then implement the format on that. In your case it would be like this:

private string FormatString(string myString)
{
    return Convert.ToInt64(myString).ToString(@"##\.##\.######\.########");
}
Ankit Sahrawat
  • 1,306
  • 1
  • 11
  • 24
  • see: "Things I've tried". I don't like this solution, because you convert the string to a long and then the long back to the string. Expect the Framework is so good and doesn't do this in the background. What I dont think. – la.urin Mar 08 '17 at 11:23