从字母数字字符串中删除字符的最快方法是什么?

时间:2017-01-04 22:17:56

标签: c# string data-manipulation

假设我们将以下字符串作为参数传递给下面的函数:

string sString = "S104";
string sString2 = "AS105";
string sString3 = "ASRVT106";

我希望能够从string中提取数字,将它们放在int变量中。有没有比以下代码更快和/或更有效的方法从字符串中删除字母?:(*这些字符串将在运行时动态填充 - 它们在构造时未分配值。)

代码:

public GetID(string sCustomTag = null)
{
    m_sCustomTag = sCustomTag;
    try {
        m_lID = Convert.ToInt32(m_sCustomTag); }
        catch{
            try{
                int iSubIndex = 0;     
                char[] subString = sCustomTag.ToCharArray(); 

                //ITERATE THROUGH THE CHAR ARRAY
                for (int i = 0; i < subString.Count(); i++)     
                {
                    for (int j = 0; j < 10; j++)
                    {
                        if (subString[i] == j)
                        {
                            iSubIndex = i;
                            goto createID;
                        }
                    }
                }

            createID: m_lID = Convert.ToInt32(m_sCustomTag.Substring(iSubIndex));
            }
            //IF NONE OF THAT WORKS...
            catch(Exception e)
            {
                m_lID = 00000;
                throw e;
            }
         }
     }
 }

我以前做过这样的事情,但我不确定是否有更有效的方法。如果它在开头只是一个字母,我可以每次将subStringIndex设置为1,但用户基本上可以放入他们想要的任何内容。一般来说,它们将被格式化为LETTER-then-NUMBER格式,但如果他们不这样做,或者他们想要输入多个字母,如sString2sString3,那么我需要能够弥补这一点。此外,如果用户输入一些非传统的非传统格式,如string sString 4 = S51A24;,是否有办法从字符串中删除任何和所有字母?

我已查看过,无法在 MSDN Google 上找到任何内容。任何帮助或链接都非常感谢!

5 个答案:

答案 0 :(得分:3)

您可以使用正则表达式。它不一定更快,但更简洁。

    return (
          <div ref='map' style={style}>
            Loading..
          </div>
        )

答案 1 :(得分:1)

您可以使用Regex,但这样做可能更快:

public int ExtractInteger(string str)
{
    var sb = new StringBuilder();
    for (int i = 0; i < str.Length; i++)
        if(Char.IsDigit(str[i])) sb.Append(str[i]);
    return int.Parse(sb.ToString());
}

您可以使用一些LINQ进一步简化,但代价是性能损失很小:

public int ExtractInteger(string str)
{
    return int.Parse(new String(str.Where(c=>Char.IsDigit(c)).ToArray()));
}

现在,如果您只想解析连续数字的第一个序列,请改为:

public int ExtractInteger(string str)
{
    return int.Parse(new String(str.SkipWhile(c=>!Char.IsDigit(c)).TakeWhile(c=>Char.IsDigit(c)).ToArray()));
}

答案 2 :(得分:1)

最快的是解析字符串而不删除任何内容:

var s = "S51A24";
int m_lID = 0;

for (int i = 0; i < s.Length; i++)
{
    int d = s[i] - '0';
    if ((uint)d < 10)
        m_lID = m_lID * 10 + d;
}

Debug.Print(m_lID + ""); // 5124

答案 3 :(得分:0)

    string removeLetters(string s)
    {
        for (int i = 0; i < s.Length; i++)
        {
            char c = s[i];

            if (IsEnglishLetter(c))
            {
                s = s.Remove(i, 1);
            }
        }

        return s;
    }

    bool IsEnglishLetter(char c)
    {
        return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
    }

答案 4 :(得分:0)

虽然你问过&#34;删除字符的最快方法是什么......&#34;您真正要说的是&#34;如何通过仅提取字符串&#34;中的数字来创建整数。

按照这个假设,由于异常抛出,你对.information{ z-index: 2; top:60px; left:0px; position:fixed; width:100%; height:100%; background:#2c3e50; opacity: 0.9; filter: Alpha(opacity=90); } 的第一次调用对于你没有数字的情况会很慢。将其更改为

Convert.ToInt32

然后,您可以使用in-place unsafe iteration of the characters of the string(这使用 if (int.TryParse(sCustomTag, out m_lID)) return; 并避免fixed中的数据复制),提取数字,然后转换它们。它避免了ToCharArray()的分配,并且比通常的方式迭代字符串要快一些。

这是一个复制/粘贴版本:

StringBuilder

如果您知道数字始终位于开头,请将 public static unsafe int GetNumber(string s) { int number; if (int.TryParse(s, out number)) return number; int value = 0; fixed (char* pString = s) { var pChar = pString; for (int i = 0; i != s.Length; i++, pChar++) { if (*pChar < '\u0030' || *pChar > '\u0039') continue; value = value * 10 + *pChar - '\u0030'; } } return value; } 更改为continue;如果数字总是在末尾,则向后迭代,转换每个单独的数字,将该数字乘以适当的10的幂,然后加到累计结果(例如,你的最后一个例子是6 * 10 < sup> 0 + 0 * 10 1 + 1 * 10 2 )直到你得到一个非数字。