Click here to Skip to main content
15,890,512 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am try to split a strings of numbers which is separated by commas to be replaced by Pipes. Also some of numbers are in range and I want to list all the numbers. EXAMPLE:
This is my table:

OLD COLUMN-------------NEW COLUMN
Original Column------------I want it change to
(1,3-6,8)--------------------(1|3|4|5|6|8)
(3,5,9,11-13,15,17)---------(3|5|9|11|12|13|15|17)

Please help, am struggling with problem.

My biggest problem is how do I get the numbers in the range. Example where it says: 3-6, it means 3,4,5,6. How do i loop or or replace the dash with all the numbers between? before replace the comas with the pipe?
Posted
Updated 28-Aug-13 13:46pm
v2

Try this:

At design-time:

1. put a Button, 'button1 on a Form
2. put two TextBoxes, 'textBox1, 'textBox2 on the same Form
3. psste the code below into the Form's .cs file
4. wire-up 'button1's Click Event Handler to 'button1_Click shown below

At run-time:

1. enter your test text into 'textBox1, click 'button1
2. examine the output in 'textBox2

The code:
C#
private StringBuilder sb = new StringBuilder();
private string[] stringAry;
private string[] seriesStringAry;
private int iStart;
private int iEnd;

private void button1_Click(object sender, EventArgs e)
{
    sb.Clear();

    stringAry = textBox1.Text.Split(',');

    foreach (string theString in stringAry)
    {
        // eliminate any white-space
        theString.Trim();

        // check for a series
        if (theString.Contains("-"))
        {
            seriesStringAry = theString.Split('-');

            // guard against bad sub-string data
            if (seriesStringAry.Length != 2) throw new InvalidDataException("malformed sub-string in your source string");

            iStart = Convert.ToInt32(seriesStringAry[0]);
            iEnd = Convert.ToInt32(seriesStringAry[1]);

            for (int i = iStart; i <= iEnd; i++)
            {
                sb.Append(i.ToString());
                sb.Append("|");
            }
        }
        else
        {
            sb.Append(theString);
            sb.Append("|");
        }
    }

    // knock off the final "|"
    sb.Remove(sb.Length - 1, 1);

    textBox2.Text = sb.ToString();
}
Discussion: This will work, but doesn't "feel like" elegant code :)

Note that the idea of assuming there is always a final "|" character here, and "knocking it off," is kind of a sloppy way of cleaning-up-after. For "production code," I (and I think you) should first: check there is a final "|," before knocking anything off. And, second, you can re-write the code to use a for-loop for the main loop, instead of foreach, in which case you can keep track of when you reach the final output of your processing, and, at that point, omit writing the "|" character. I was just lazy here, sorry.

What would happen if you wanted an entry in the text you were parsing to be in a form like this: "15-11" ? The code here would fail, in that case, but it would not be that difficult to re-write the code to handle that case.

Note, also, that the assumption here is: the strings in the data you parse always represent integers.

Now, what would be really "elegant" would be to see one of CP's RegEx experts add an answer to this question using only RegEx !
 
Share this answer
 
Comments
CodeBuks 27-Sep-13 22:07pm    
+5 Nice work! Great answer!
Hi In the following code example I am using the regular expression engine in order
to retrieve the target numbers from the input string into the min & max groups
from there its a simple loop creating the output string.

C#
string r = "3,5,9,11-13,15,17";

StringBuilder sb = new StringBuilder();
MatchCollection matches = 
                Regex.Matches(r, "(?:(?<min>[0-9]+)(?:-(?<max>[0-9]+))?)");

foreach (Match match in matches)
{
   sb.Append(match.Groups["min"].Value);
   sb.Append("|");
     
   if (!string.IsNullOrWhiteSpace(match.Groups["max"].Value))
   {
      int max = int.Parse(match.Groups["max"].Value);
      for (int i = int.Parse(match.Groups["min"].Value) + 1; i <= max; i++)
      {
         sb.Append(i);
         sb.Append("|");                
      }
   }
}
sb.Remove(sb.Length - 1, 1);
 
Share this answer
 
v2
Comments
BillWoodruff 29-Aug-13 21:02pm    
Nice work: a few comments:

1. IsNullOrWhiteSpace requires FrameWork >= 4.0, or Client FrameWork 4.0.

2. there is something strange going on, however, when you have more than one pair-to-be-expanded, , or duplicated values, or "ordinality" in the input list is changed:

a. string r = "9,11-13,4-7,15,17,5,3";
returns: 9|11|12|13|15|17|5|3|79|11|12|13|15|17|5|3|7

b. string r = "9,4-7,11-13,15,17,5,3";
returns: 9|11|12|13|15|17|5|3|79|11|12|13|15|17|5|3|79|11|12|13|15|17|5|3|7

c. string r = "3,4,5,9,11-13,4-5,15,17";
returns: 3|5|9|4|5|6|7|11|12|13|15|173|5|9|4|5|6|7|11|12|13|15|17

d. string r = "3,4,4-5,5,9,11-13,15,17";
returns: 3|5|9|4|5|6|7|11|12|13|15|173|5|9|4|5|6|7|11|12|13|15|173|5|9|4|5|6|7|11|12|13|15|17

e. string r = "3,4,5-7,8,9,11-13,15,17";
returns: 3|5|9|4|5|6|7|11|12|13|15|173|5|9|4|5|6|7|11|12|13|15|173|5|9|4|5|6|7|11|12|13|15|173|5|9|4|5|6|7|11|12|13|15|17

f. string r = "3,4,5-7,8,9,10,11-13,14,15-17";
returns: 3|5|9|4|5|6|7|11|12|13|15|173|5|9|4|5|6|7|11|12|13|15|173|5|9|4|5|6|7|11|12|13|15|173|5|9|4|5|6|7|11|12|13|15|173|5|9|4|5|6|7|11|12|13|15|173|5|9|4|5|6|7|11|12|13|15|17

It's results like that discourage me from using RegEx, but I don't doubt it's a very powerful tool, and I bet you could alter your solution to handle the cases just shown.

The result shown in case "f." above puzzled me, because I thought, in that case, the list was sequential, there are no "gaps," and there were no duplicates; I thought "f." would work.
Nissim Salomon 31-Aug-13 5:14am    
Hi
First, I think the problem is at your end.
For example when I'm using your input (from the f section) I am getting the following result
3|4|5|6|7|8|9|10|11|12|13|14|15|16|17 as expected.
I don't think that the following problems relate to the use with regular expression.
second, you can use the string.IsNullOrEmpty instead of string.IsNullOrWhiteSpace (supported from .net framework 2.0)
Please copy the following code into a Console Application and let me know if the problems still exist
BillWoodruff 5-Sep-13 2:42am    
Hi Nissims, I copied your code exactly, and using a Console would give no different results than using output to a TextBox in a WinForms app. I think it would enhance the value of your solution here if you added the information about the option to use string.IsNullOrEmtpy.

yours, Bill
Try this:
string[] newString = oldString.Split(',');


The "newString" array will have all the items separated and you can concatenate the individual values.

or

do this:
string newString = oldString.Replace(",","|");


This will just replace the commas with vertical pipes.
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900