Как отделить символ и номер от строки

Например, я хотел бы выделить:

  • OS234 до OS и 234
  • AA4230 - AA и 4230

Я использовал следующее тривиальное решение, но я совершенно уверен, что должно быть более эффективное и надежное решение.

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; }


        }

Ответ 1

Я использовал bniwredyc для получения улучшенной версии моей программы:

    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;
        }

Ответ 2

Регулярные выражения лучше всего подходят для такого рода работ:

using System.Text.RegularExpressions;

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

string alphaPart = result.Groups[1].Value;
string numberPart = result.Groups[2].Value;

Ответ 3

Используйте Linq для этого

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);

Ответ 4

Если вы хотите разрешить больше вхождений char с последующим номером или наоборот, вы можете использовать

private string SplitCharsAndNums(string text)
{
    var sb = new StringBuilder();
    for (var i = 0; i < text.Length - 1; i++)
    {
        if ((char.IsLetter(text[i]) && char.IsDigit(text[i+1])) ||
            (char.IsDigit(text[i]) && char.IsLetter(text[i+1])))
        {
            sb.Append(text[i]);
            sb.Append(" ");
        }
        else
        {
            sb.Append(text[i]);
        }
    }

    sb.Append(text[text.Length-1]);

    return sb.ToString();
}

И затем

var text = SplitCharsAndNums("asd1 asas4gr5 6ssfd");
var tokens = text.Split(' ');

Ответ 5

Каждый и их мать дадут вам решение с использованием регулярного выражения, так что здесь нет:

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

Ответ 6

Мне действительно нравится ответ Джейсона. Здесь нам не нужно регулярное выражение. Мое решение для обработки ввода типа "H1N1":

public static IEnumerable<string> SplitAlpha(string input)
{
    var words = new List<string> { string.Empty };
    for (var i = 0; i < input.Length; i++)
    {
        words[words.Count-1] += input[i];
        if (i + 1 < input.Length && char.IsLetter(input[i]) != char.IsLetter(input[i + 1]))
        {
            words.Add(string.Empty);
        }
    }
    return words;
}

Это решение линейно (O (n)).

Ouput

"H1N1" -> ["H", "1", "N", "1"]
"H" -> ["H"]
"GH1N12" -> ["GH", "1", "N", "12"]
"OS234" -> ["OS", "234"]

Ответ 7

Вы делаете это для сортировки? Если это так, имейте в виду, что Regex может убить производительность для больших списков. Я часто использую AlphanumComparer, который является общим решением этой проблемы (может обрабатывать любую последовательность букв и цифр в любом порядке). Я считаю, что я адаптировал его из эту страницу.

Даже если вы не сортируете его, использование подхода "по-символу" (если у вас есть переменная длина) или простая подстрока/синтаксический анализ (если они исправлены) будут намного эффективнее и проще в тестировании чем регулярное выражение.

Ответ 8

Совместимость с .NET 2.0, без регулярного выражения

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();
    }
}

Ответ 9

Просто используйте функцию substring и установите положение внутри кронштейна.

 String id = "DON123";
 System.out.println("Id nubmer is : "+id.substring(3,6));

Ответ:

 Id number is: 123

Ответ 10

используйте Split для выделения строки из sting, использующей вкладку \t и пробел

string s = "sometext\tsometext\tsometext";
string[] split = s.Split('\t');

теперь у вас есть массив строк, который вы хотите слишком легко