用字母和数字分割字符串,如C420F140000

时间:2014-06-18 12:21:48

标签: c# vb.net string split

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

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

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

低于10的所有数字前面都有一个0,例如01.

我尝试了一些正则表达式的例子,但它们的速度很慢。

有关在VB.Net or C#

中有效执行此提取的任何建议

5 个答案:

答案 0 :(得分:2)

我建议使用正则表达式来解决这个问题。

尝试类似

的模式
[A-Z][0-9]{2,3}

这将查找带有尾随数字的前导大写字母。

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

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

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

在评论中进一步了解详情:

尝试

((E|F|T)[0-9]{2}|C[0-9]{3})

这将确保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);
}

答案 1 :(得分:2)

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

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

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

答案 2 :(得分:1)

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

答案 3 :(得分:0)

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

这是一个粗略的草图,可行。有意排除变量和细节。这是手动和简约的方法,如果没有并行化,很难更快。您可能也会从搜索和剪切延迟(按需)或本地化(仅从索引搜索到索引...)中获益,但这很大程度上取决于系统的其他位。

答案 4 :(得分:0)

我认为这应该有效。我唯一担心的是你怎么知道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(' ');