如何从字符串中分隔字符和数字部分

时间:2009-12-28 05:04:14

标签: c# string

例如,我想分开:

  • OS234OS234
  • AA4230AA4230

我使用了以下简单的解决方案,但我确信应该有一个更有效和更强大的解决方案。

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


        }

11 个答案:

答案 0 :(得分:20)

正则表达式最适合此类工作:

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;

答案 1 :(得分:8)

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

答案 2 :(得分:4)

如果您想要解决更多出现的char后跟数字,反之亦然,您可以使用

from kivy.app import App
from kivy.uix.popup import Popup
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.scrollview import ScrollView
from kivymd.list import MDList, OneLineListItem,TwoLineListItem
from kivy.lang import Builder
from kivymd.label import MDLabel
from kivymd.button import MDFlatButton,MDRaisedButton
import threading
from models_sql import *
from kivy.properties import ObjectProperty
from kivymd.textfields import SingleLineTextField
from kivymd.spinner import MDSpinner
from kivy.uix.floatlayout import FloatLayout
session = Session()


kv = ''' 
Testimonies:
    Button:

        text: " Testify"
        size_hint: None, None
        size: 4 * dp(40), dp(40)
        pos_hint: {'center_x': 0.2, 'center_y': 0.3}
        font_name: 'Roboto-Regular'
        on_release: root.share();



<F>:
    name: name
    message: message

    id: sub_button
    title: 'Share Your Testimony'
    markup: True
    size_hint: .9, None
    height: dp(300)
    pos_hint:{'center_x': 0.5, 'center_y': 0.65}
    FloatLayout:
        SingleLineTextField:
            id: name
            hint_text: 'Name'
            multiline: False
            pos_hint:{'center_x': 0.5, 'center_y': 0.8}
        SingleLineTextField:
            id: message
            hint_text: 'Message'
            multiline: True
            pos_hint:{'center_x': 0.5, 'center_y': 0.5}

        MDFlatButton:
            text: 'ShieeeeeeM)'
            pos_hint:{'center_x': 0.5, 'center_y': 0.2}
            on_press: root.shiemor()


<DBScroll>:
    id: dbscroll
    title: ''
    size_hint: None, None
    size: 400,100
    FloatLayout:
        Label:
            text: 'Sending'
            pos_hint:{'center_x': 0.8, 'center_y': 0.7}
            size_hint: None, None
            size: 50,100

        MDSpinner:
            size_hint: None,None
            size: dp(30),dp(30)
            pos_hint:{'center_x': 0.2, 'center_y': 0.7}

''' 



class DBScroll(Popup):
    pass

class F(Popup):
    stop = threading.Event()
    name = ObjectProperty(None)
    message = ObjectProperty(None)

    def __init__(self, **kwargs):
        super(F, self).__init__(**kwargs)

    def start_second_thread(self):
        threading.Thread(target=self.popman()).start()

    def shiemor(self):
        self.start_second_thread()
        print('starting thread')
        add_testimony = Testify(name=self.ids.name.text, message=self.ids.message.text)
        session.add(add_testimony)
        print(' connecting to external db')

        session.commit()
        self.ids.name.text= ""
        self.ids.message.text= ''
        print('done ')
        #self.dismiss() use this to close the popUp


    def popman(self):
        pop = DBScroll(auto_dismiss=True)
        pop.open()





class Testimonies(BoxLayout):
    def __init__(self, **kwargs):
        super(Testimonies, self).__init__(**kwargs)

    def share(self):
        pop = F()
        pop.open()



class Stack(App):
    def build(self):
        #return Testimonies()
        return Builder.load_string(kv)


if __name__=="__main__":
    Stack().run()

然后

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

答案 3 :(得分:3)

每个人和他们的母亲都会使用正则表达式给你一个解决方案,所以这里有一个不是:

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

答案 4 :(得分:2)

我真的很喜欢jason's answer。我们这里不需要正则表达式。我处理输入的解决方案,例如&#34; H1N1&#34;:

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

输出中

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

答案 5 :(得分:1)

你这样做是为了分类吗?如果是这样,请记住,正则表达式可以杀死大型列表的性能。我经常使用AlphanumComparer这是这个问题的一般解决方案(可以按任何顺序处理任何字母和数字序列)。我相信我是从this page改编而来的。

即使您没有对其进行排序,使用逐字符方法(如果您有可变长度)或简单的子字符串/解析(如果它们已修复)将更有效且更容易测试而不是正则表达式。

答案 6 :(得分:1)

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

答案 7 :(得分: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;
        }

答案 8 :(得分:0)

只需使用else功能并设置支架内的位置即可。

substring

答案:

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

答案 9 :(得分:-1)

使用其他答复中的想法,我这样做了,在这种情况下,我需要将结果作为整数“时间表”和字符串“ rack”

   int schedule=0;
   char c;
   string rack=string.Empty;
   for (i=0; i<inputString.Length; i++)
   {
    c=inputString[i];
    if (Char.IsDigit(c))
    {
     schedule=(10*schedule)+(c-'0');
    }
    else
    {
     rack+=c.ToString();
    }
   }

答案 10 :(得分:-2)

使用Split从使用tab \ t和space

的sting中分离字符串
string s = "sometext\tsometext\tsometext";
string[] split = s.Split('\t');

现在你有一个你想要的字符串数组