2

How to convert the string into the given pattern. Consider pattern can be anything.

Example:

  • Input String is - 1234567890
  • For Pattern XXXX-XXXX-XX Then Output is - 1234-5678-90
  • For Pattern XXX-XXX-XXX-X Then Output is - 123-456-789-0
  • For Pattern XXX=XXX=XXX=X Then Output is - 123=456=789=0
  • For Pattern XX-XXX-X-XXXX Then Output is - 12-345-6-7890

Note: Length of input string may vary.

I have tried as

Console.WriteLine(Regex.Replace("1235645847", ".{1,4}", "$&-").TrimEnd('-'));

But it is not dynamic it's working for the first pattern only.

Is it possible to achieve this? Any help is appreciated.

5
  • 1
    Most likely, it is possible to achieve. If you post, what you have tried, people tend to give you better answers. Commented Sep 28, 2018 at 5:04
  • If you are not familiar with regular expression, go have a read regular-expressions.info Commented Sep 28, 2018 at 5:14
  • 1
    StackOverflow is not a code-writing service. Show us what you have done so far and what is your problem? Btw, as for me, XXXXXXXXX*X pattern should produce 123456789*0, no? Commented Sep 28, 2018 at 5:16
  • I have included the same pattern but * is creating issues while displaying so changed to "=" Commented Sep 28, 2018 at 5:19
  • 2
    This is not a question about pattern matching or regular expressions. This is a formatting question. Please edit your tags and provide a minimum set of code that demonstrates what you are trying to do so we can help you. Commented Sep 28, 2018 at 5:22

3 Answers 3

3

As already said, this is question has nothing in common with regex. Well, except pattern, but you using it in diferent context. You need just to format some strings, using some pattern.

You could use this function for example:

public string ConvertToFormat(string strToFormat, string pattern)
{
  if (pattern.Count(c => c == 'X') != strToFormat.Length)
    throw new ArgumentException("Number of placeholders in pattern is different from number of characters in the input string!");
  StringBuilder sb = new StringBuilder();
  int j = 0;
  for(int i = 0; i < pattern.Length; i++)
    if (pattern[i] == 'X')
    {
      sb.Append(strToFormat[j]);
      j++;
    }
    else
      sb.Append(pattern[i]);

  return sb.ToString();
}

and use like this:

string result = ConvertToFormat("1234567890", "XXXX-XXXX-XX");
result = ConvertToFormat("1234567890", "XXX-XXX-XXX-X");
result = ConvertToFormat("1234567890", "XXX=XXX=XXX=X");

UPDATE

Dynamic solution with regtex:

public string RegexConvertToFormat(string strToFormat, int blockSize, char separator)
{
  return Regex.Replace("1235645847", ".{" + blockSize + "}" , "$&" + separator).TrimEnd(separator);
}

Usage:

string s = RegexConvertToFormat("1234567890", 4, '-');
s = RegexConvertToFormat("1234567890", 3, '-');
s = RegexConvertToFormat("1234567890", 3, '=');
Sign up to request clarification or add additional context in comments.

4 Comments

Michal, I have tried a similar solution this is definitely a good way. But is this same possible with Regex.
@SumitDeshpande This is not appropriate task for regex, it cannot be done with it.
Yes this is working but I am looking for blocksize as dynamic. Ex. XX-XXX-X-XX.
@SumitDeshpande Well, it could be done with regex, but it would be the worst method to accomplish it. The best you could do is supply array of indexes where separators have to be inserted.
3
string input="123456789";
var pattern="XXX-XXX=XXX";

var reg=new Regex(new string('N',input.Length).Replace("N","(\\w)"));//1.
var regX=new Regex("X");
for (int i = 1; i <= input.Length; i++)
{
    pattern=regX.Replace(pattern,"$"+i.ToString(),1);//2.
}
Console.WriteLine( reg.Replace(input,pattern));

enter image description here


1. replace input 123456789 to (\w)(\w)(\w)(\w)(\w)(\w)(\w)(\w) multi groups

  1. replace pattern XXX-XXX=XXX to groups replacement $1$2$3-$4$5$6=$7$8$9

Comments

1

A simple Linq will do:

public static string ApplyPattern(string value, string mask) {
  if (null == value)
    throw new ArgumentNullException("value");
  else if (null == mask)
    throw new ArgumentNullException("mask");
  else if (mask.Count(c => c == 'X') != value.Length)
    throw new ArgumentException("Inconsistent mask", "mask"); 

  int index = 0;

  // index++ - side effect - which is, however, safe in the context
  return string.Concat(mask
    .Select(c => c == 'X' ? value[index++] : c));
}

Demo:

string[] testMasks = new string[] {
  "XXXX-XXXX-XX",
  "XXX-XXX-XXX-X",
  "XXX=XXX=XXX=X",
  "XX-XXX-X-XXXX",
  "+XX-=XXX-X--XXXX",
  "+(XX)=XXX-X--XXXX?",
};

string report = string.Join(Environment.NewLine, testMasks
  .Select(mask => $"{mask,20} -> {ApplyPattern("1234567890", mask)}"));

Console.Write(report);

Outcome:

XXXX-XXXX-XX         -> 1234-5678-90
XXX-XXX-XXX-X        -> 123-456-789-0
XXX=XXX=XXX=X        -> 123=456=789=0
XX-XXX-X-XXXX        -> 12-345-6-7890
+XX-=XXX-X--XXXX     -> +12-=345-6--7890
+(XX)=XXX-X--XXXX?   -> +(12)=345-6--7890?

Comments

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.