Question

I am trying to split the following string

string v = "A: 1,5 ,B:2,44,C: 3,54,D: 5,11";

string[] val = v.Split(',');

for (int i = 0; i < val.Length; i++)
{
    val[i] = val[i].ToString().Trim();
}

The problem is that there are numbers with commas inside so the splitting is not correct. Is there a way to get for example in my array the correct values "A:1,5","B:2,44","C:3,54","D:5,11"? I am using C# 2.0

Was it helpful?

Solution

If your format must be a letter followed by a colon then a floating point number, with commas separating the entries:

string patternDelim = @"([A-Z]):"; // split on 'X:'
//                    @"([A-Z]+):" // split on 'ABC:'
//                    @"([A-Z][A-Z0-9]*):" // split on 'A1B2C3:'
string[] values = Regex.Split(input, patternDelim);

Because we've used a capturing group as a delimiter, it will end up in our output. So, at this point we've carved up the input into something like this:

A
 1,5 ,
B
2,44,
C
 3,54,
D
 5,11

Now we just need to extract these into their actual pairs of data:

Dictionary<string, string> pairs = new Dictionary<string, string>();
for (int ii = 0; ii < values.Length; ++ii)
{
    // empty values are skipped
    if (values[ii].Length == 0) continue;

    string value = values[ii + 1].Trim()
                                 .TrimEnd(','); // remove any trailing commas

    pairs.Add(values[ii], value.TrimEnd());
    ii++; // use two each time
}

This will result in a dictionary of key-value pairs like so:

A = 1,5
B = 2,44
C = 3,54
D = 5,11

Which you can parse as you wish using the appropriate CultureInfo or NumberFormatInfo. Note, this will also work for all manner of decimal separators, and even if thousands separators are present:

Input = A: 1.000,5 ,B:2,44,C: 3,54e+38,D: -,11

A = 1.000,5
B = 2,44
C = 3,54e+38
D = -,11

OTHER TIPS

string v = "A: 1,5 ,B:2,44,C: 3,54,D: 5,11";

string[] val = Regex.Matches(v, @"\w+\s*\:\s*\d+\s*\,\s*\d+")
                    .Cast<Match>()
                    .Select(m => m.Value)
                    .ToArray();

If the source string cannot be changed I would split on letters:

v.Split(new[] {'A', 'B', 'C', 'D'});

or

v.Split(new[] {"A:", "B:", "C:", "D:"});

and than tidied up the resulting parts.

Another ugly alternative, works though

static void Main(string[] args)
{
    string v = "A: 1,5 ,B:2,44,C: 3,54,D: 5,11";
    IEnumerable<string> result = Foo(v).ToArray();
    // A: 1,5
    // B:2,44
    // C: 3,54
    // D: 5,11
}

public static IEnumerable<string> Foo(string s)
{
    var sb = new StringBuilder();
    bool shouldFlush = false;
    bool firstIteration = true;
    foreach (char c in s)
    {
        if (!firstIteration)
        {
            shouldFlush = char.IsLetter(c);
        }
        if (shouldFlush)
        {
            string result = sb.ToString().Trim(' ', ',');
            sb.Clear();
            yield return result;
        }

        sb.Append(c);
        firstIteration = false;
    }

    yield return sb.ToString().Trim(' ', ',');
}
string v = "A: 1,5 ,B:2,44,C: 3,54,D: 5,11";
string outstr = Regex.Replace(v, "([A-Z-a-z]+)(: *)([0-9]+,*[0-9]*)([ ,]*)", "$1:$3_");
string[] newStringArray = outstr.Split('_');

Quick answer (untested):

string[] parts = v.Split(',');
List<string> grouped = new List<string>();

for(int i = 0; i < parts.Length; i++)
    grouped.Add(parts[i].Trim() + "," + parts[++i].Trim());
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top