سؤال

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

هل كانت مفيدة؟

المحلول

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

نصائح أخرى

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());
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top