C# 使用字母和数字拆分字符串,如C420F140000

C# 使用字母和数字拆分字符串,如C420F140000,c#,vb.net,string,split,C#,Vb.net,String,Split,我有一个字符串“F12C429C420T16000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000” 需要在每个字母上拆分,使其看起来像F12 C429 C420 T16,并将每个字母放入一个数组中 此字符串的固

我有一个字符串“
F12C429C420T16000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000”
需要在每个字母上拆分,使其看起来像F12 C429 C420 T16,并将每个字母放入一个数组中

此字符串的固定长度为90,可能没有错误代码(全零)或一个或多个错误代码

所有代码都以字母开头,后跟2到3位数字

10以下的所有数字前面都有0,例如01

我试过一些正则表达式的例子,但它们的速度较慢

VB.Net或C#

  • 扫描字符串并计数字母,或以任何其他方式找出数字
  • 预先分配一个具有该大小的空字符串数组,所有条目为空
  • 运行for循环,该循环将扫描从0到字符串末尾的索引
  • 在该循环内运行第二个较小的循环,该循环将检测数字/字母边缘
  • 检测到边缘后,从最后一个字母到边缘生成一个子字符串,并将其写入下一个数组条目

那是一个大概的草图,会有用的。故意排除变量和细节。这是一种手动且极简的方法,如果没有并行化,很难加快速度。有时,您可能会从使搜索和剪切变为惰性(按需)或本地化(仅从索引…搜索到索引…)中获益,但这在很大程度上取决于系统的其他部分。

我建议使用正则表达式来解决此问题

试着像

[A-Z][0-9]{2,3}
这将查找带尾随数字的前导大写字母

但是,正如在您的示例中一样,由于底层字符串的原因,这不是一个完美的解决方案。例如,在示例中,最后一个代码可以是
T16
T160

如果错误代码列表是有限的,那么最好创建一个查找表

如果要生成列表,最好使用不同的填充字符来消除上述歧义

以下是评论中的一些进一步细节:

试一试

这将确保E/F/T后跟两位数字,而c后跟3。然后删除上面提到的歧义。因此,您的完整代码可能如下所示

Regex expr = new Regex("((E|F|T)[0-9]{2}|C[0-9]{3})");
MatchCollection matches = expr.Matches("F12C429C420T160000000000000000000000000000000000000000000000000000000000000000000000000000");
foreach (Match matchedCode in matches)
{
    Console.WriteLine(matchedCode.Value);
}

我将为此编写一个方法。您可以简单地循环所有字符并将所有标记放入一个列表中。使用
Char.IsDigit
Char.islitter

Public Shared Function SplitByLetter(text As String) As String()
    Dim list As New List(Of String)
    Dim sb As New System.Text.StringBuilder()

    For Each chr As Char In text
        If Char.IsLetter(chr) Then
            If sb.Length > 0 Then list.Add(sb.ToString())
            sb.Clear()
        End If
        sb.Append(chr)
    Next
    If sb.Length > 0 Then list.Add(sb.ToString())
    Return list.ToArray()
End Function
使用示例字符串:

Dim text As String = "F12C429C420T160000000000000000000000000000000000000000000000000000000000000000000000000000"
Dim tokens As String() = SplitByLetter(text)
For Each part As String In tokens
    Console.WriteLine(part)
Next
输出为:

F12
C429
C420
T160000000000000000000000000000000000000000000000000000000000000000000000000000
我不知道最后一个标记是否正确,你没有提到。当令牌长度超过3个字符时,您可能希望停止,然后更改
(如果
):

If sb.Length >= 4 OrElse Char.IsLetter(chr) Then
结果是:

F12
C429
C420
T160
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
0000
000

我认为这应该行得通。我唯一关心的是,你如何知道T16和T160之间的区别

string s = "F12C429C420T160000000000000000000000000000000000000000000000000000000000000000000000000000";
        string result = "";
        foreach (char c in s.TrimEnd('0'))
        {
            if( c > 64)result+=c;
            else result+=' '+c;
        }
        string[] final = result.Split(' ');
类程序
{    
静态void Main(字符串[]参数)
{
列表单词=新列表();
字串=”;
string str=“F12C429C420T1600000000000000000000000
0000000000000000000000000000000000000000";
foreach(char-ch-in-str)
{
if(字符(ch))
{
添加(word);
word=ch.ToString();
}
其他的
{
word+=ch.ToString();
}
}
添加(word);
字。删除(0);
}
}

您好,您试过什么?OP说他试过正则表达式,但没有显示出来。好。单词。想要的结果是什么?你有没有尝试过类似于
新正则表达式(([A-Z][0-9]{2,3})。匹配(“F12C429C420T16000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000”)
?顺便说一句:OP在评论中提到想要的结果是将T16作为最后一项。+1用于注意T16/T160的歧义。OP刚刚在评论中说,期望的结果是将T16作为最后一项。@Quetzalcatl感谢更新,OP应该首先澄清细节:)@user3752477他们还有其他要求吗?字符串只有90个字符,所以并行化很难加快速度。@Gabe-字符串有90个字符,但若有数百万个字符串,那个么并行化可能是合理的。我们再次进入OP没有提供的位。
所有代码都以字母开头,后跟2到3位。
最后一位是s/b T16。我确实有一个非常基本的方法,但比你的方法慢,效果很好,除了fpr最后一项,E,F和Ts是字母加2位,C是C加3位。@Neolick:你说得对,如果某人的长度>=4而不是
>4
,那么它一定是
,更正了。@user3752447:对不起,我刚刚注意到你已经发表了评论。零总是在末尾吗?结束错误代码的规则是什么?如果后面至少有两个零,是否达到了最后一个错误代码?添加一些解释不会有什么坏处。
string s = "F12C429C420T160000000000000000000000000000000000000000000000000000000000000000000000000000";
        string result = "";
        foreach (char c in s.TrimEnd('0'))
        {
            if( c > 64)result+=c;
            else result+=' '+c;
        }
        string[] final = result.Split(' ');
class Program
    {    
        static void Main(string[] args)
        {
            List<string> words=new List<string>();                
            string word="";
            string str = "F12C429C420T16000000000000000000000000000000000000
                                     0000000000000000000000000000000000000000";
            foreach (char ch in str)
            {
                if (char.IsLetter(ch))
                {
                    words.Add(word);
                    word = ch.ToString();
                }
                else
                {
                    word += ch.ToString();
                }
            }
            words.Add(word);
            words.RemoveAt(0);
        }
      }