using System.Collections;
using System.Collections.Generic;
using System.Globalization;
namespace Abacus.Framework.Utilities
public static void Main()
var items = new List<string> { "China", "[Test]", "alpha 1", "alpha 10", "alpha 2", "alpha 9" };
var sorter = new StringNumericComparer();
var sortedItems = items.OrderBy(i => i, sorter).ToList();
foreach (var item in sortedItems)
public class StringNumericComparer : IComparer<string>, IComparer
public int Compare(string x, string y)
if (ReferenceEquals(x, y))
int secondLen = y.Length;
int firstPos = 0, secondPos = 0;
for (; firstPos < firstLen && secondPos < secondLen; firstPos++, secondPos++)
char firstChar = x[firstPos];
char secondChar = y[secondPos];
if (char.IsDigit(firstChar) && char.IsDigit(secondChar))
double firstValue = ParseDouble(x, ref firstPos);
double secondValue = ParseDouble(y, ref secondPos);
if (firstValue != secondValue)
return firstValue > secondValue ? 1 : -1;
int order = char.ToUpperInvariant(firstChar).CompareTo(char.ToUpperInvariant(secondChar));
return Math.Sign((firstLen - firstPos) - (secondLen - secondPos));
private static double ParseDouble(string value, ref int pos)
int length = value.Length;
for (pos++; pos < length && char.IsDigit(value[pos]); pos++)
int numLength = pos - start;
return double.Parse(value.Substring(start, numLength), CultureInfo.InvariantCulture);
catch (OverflowException)
int IComparer.Compare(object x, object y)
return Compare(x as string, y as string);