tags:

views:

139

answers:

6

eg : I would like to seperate OS234 to OS and 234 AA4230 to AA and 4230

I have used following trival soultion ,but I am quite sure that there should be some more efficient and robust solution .

private void demo()
    {   string cell="ABCD4321";
        int a = getIndexofNumber(cell);
        string Numberpart = cell.Substring(a, cell.Length - a);
        row = Convert.ToInt32(rowpart);
        string Stringpart = cell.Substring(0, a);
    }

private int getIndexofNumber(string cell)
        {
            int a = -1, indexofNum = 10000;
            a = cell.IndexOf("0"); if (a > -1) { if (indexofNum > a) { indexofNum = a; } }
            a = cell.IndexOf("1"); if (a > -1) { if (indexofNum > a) { indexofNum = a; } }
            a = cell.IndexOf("2"); if (a > -1) { if (indexofNum > a) { indexofNum = a; } }
            a = cell.IndexOf("3"); if (a > -1) { if (indexofNum > a) { indexofNum = a; } }
            a = cell.IndexOf("4"); if (a > -1) { if (indexofNum > a) { indexofNum = a; } }
            a = cell.IndexOf("5"); if (a > -1) { if (indexofNum > a) { indexofNum = a; } }
            a = cell.IndexOf("6"); if (a > -1) { if (indexofNum > a) { indexofNum = a; } }
            a = cell.IndexOf("7"); if (a > -1) { if (indexofNum > a) { indexofNum = a; } }
            a = cell.IndexOf("8"); if (a > -1) { if (indexofNum > a) { indexofNum = a; } }
            a = cell.IndexOf("9"); if (a > -1) { if (indexofNum > a) { indexofNum = a; } }

            if (indexofNum != 10000)
            { return indexofNum; }
            else
            { return 0; }


        }
+2  A: 

Use Linq to do this

string str = "OS234";

var digits = from c in str
             select c
             where Char.IsDigit(c);

var alphas = from c in str
             select c
             where !Char.IsDigit(c);
this. __curious_geek
+1 clean solution
JL
This seems to be good solution ,but unfortunately .net 2.0 users could not use Linq
Thunder
I recomend - upgrade to C# 3.0.
this. __curious_geek
+6  A: 

Regular Expressions are best suited for this kind of work:

Regex re = new Regex(@"([a-zA-Z]+)(\d+)")
Match result = re.Match(input)

string alphaPart = result.Groups[1];
string numberPart = result.Groups[2];
x0n
Might want to add two lines to this answer: string alphaPart = result.Groups[1]; string numberPart = result.Groups[2];
Brett Daniel
Following seems to be more complete solution: Regex re = new Regex(@"([a-zA-Z]+)(\d+)"); Match result = re.Match("as23"); string alphaPart = result.Groups[1].ToString (); string numberPart = result.Groups[2].ToString();
Thunder
Isn't it `result.Groups[1].Value`?
Dmitri Nesteruk
result.Groups[2].ToString(); Worked for meFurther we should add Imports Systems.Text.Regularexpression @ top.
Thunder
thanks for the fixes, all.
x0n
+2  A: 

Everyone and their mother will give you a solution using regex, so here's one that is not:

 // s is string of form ([A-Za-z])*([0-9])*
 int index = s.IndexOfAny(new[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' });
 string chars = s.Substring(0, index);
 int num = Int32.Parse(s.Substring(index));
Jason
+1  A: 

Are you doing this for sorting purposes? If so, keep in mind that Regex can kill performance for large lists. I frequently use an AlphanumComparer that's a general solution to this problem (can handle any sequence of letters and numbers in any order). I believe that I adapted it from this page.

Even if you're not sorting on it, using the character-by-character approach (if you have variable lengths) or simple substring/parse (if they're fixed) will be a lot more efficient and easier to test than a Regex.

Aaronaught
+1  A: 

.NET 2.0 compatible, without regex

public class Result
{
    private string _StringPart;
    public string StringPart
    {
        get { return _StringPart; }
    }

    private int _IntPart;
    public int IntPart
    {
        get { return _IntPart; }
    }

    public Result(string stringPart, int intPart)
    {
        _StringPart = stringPart;
        _IntPart = intPart;
    }
}

class Program
{
    public static Result GetResult(string source)
    {
        string stringPart = String.Empty;
        int intPart;
        var buffer = new StringBuilder();
        foreach (char c in source)
        {
            if (Char.IsDigit(c))
            {
               if (stringPart == String.Empty)
               {
                    stringPart = buffer.ToString();
                    buffer.Remove(0, buffer.Length);
                }
            }

            buffer.Append(c);
        }

        if (!int.TryParse(buffer.ToString(), out intPart))
        {
            return null;
        }

        return new Result(stringPart, intPart); 
    }

    static void Main(string[] args)
    {
        Result result = GetResult("OS234");
        Console.WriteLine("String part: {0} int part: {1}", result.StringPart, result.IntPart);
        result = GetResult("AA4230 ");
        Console.WriteLine("String part: {0} int part: {1}", result.StringPart, result.IntPart);
        result = GetResult("ABCD4321");
        Console.WriteLine("String part: {0} int part: {1}", result.StringPart, result.IntPart);
        Console.ReadKey();
    }
}
bniwredyc
Looks quite over engineered!
this. __curious_geek
@this.__curious_geek yep. I like Jasons solution.
bniwredyc
+1  A: 

I have used bniwredyc's answer to get Improved version of my routine:

    private void demo()
        {
            string cell = "ABCD4321";
            int row, a = getIndexofNumber(cell);
            string Numberpart = cell.Substring(a, cell.Length - a);
            row = Convert.ToInt32(Numberpart);
            string Stringpart = cell.Substring(0, a);
        }

        private int getIndexofNumber(string cell)
        {
            int indexofNum=-1;
            foreach (char c in cell)
            {
                indexofNum++;
                if (Char.IsDigit(c))
                {
                    return indexofNum;
                }
             }
            return indexofNum;
        }
Thunder