从一个字符串中解析一个数字,其中包含非数字

时间:2010-07-08 14:32:44

标签: c#

我正在研究.NET项目,我试图只解析字符串中的数值。例如,

string s = "12ACD";
int t = someparefun(s); 
print(t) //t should be 12

有几个假设是

  1. 字符串模式始终为数字后跟字符。
  2. 数字部分始终为一位或两位数值。
  3. 是否有任何C#预定义函数来解析字符串中的数值?

11 个答案:

答案 0 :(得分:29)

没有这样的功能,至少我不知道。但是一种方法是使用正则表达式删除不是数字的所有内容:

using System;
using System.Text.RegularExpressions;

int result =
    // The Convert (System) class comes in pretty handy every time
    // you want to convert something.
    Convert.ToInt32(
        Regex.Replace(
            "12ACD",  // Our input
            "[^0-9]", // Select everything that is not in the range of 0-9
            ""        // Replace that with an empty string.
    ));

此功能会为12产生12ABC,因此如果您需要能够处理负数,则需要一个不同的解决方案。它也不安全,如果你只传递非数字,它将产生FormatException。以下是一些示例数据:

"12ACD"  =>  12
"12A5"   =>  125
"CA12A"  =>  12
"-12AD"  =>  12
""       =>  FormatException
"AAAA"   =>  FormatException

更简洁但更安全的方法是使用int.TryParse()

using System;
using System.Text.RegularExpression;

public static int ConvertToInt(String input)
{
    // Replace everything that is no a digit.
    String inputCleaned = Regex.Replace(input, "[^0-9]", "");

    int value = 0;

    // Tries to parse the int, returns false on failure.
    if (int.TryParse(inputCleaned, out value))
    {
        // The result from parsing can be safely returned.
        return value;
    }

    return 0; // Or any other default value.
}

再次提供一些示例数据:

"12ACD"  =>  12
"12A5"   =>  125
"CA12A"  =>  12
"-12AD"  =>  12
""       =>  0
"AAAA"   =>  0

或者,如果你只想要字符串中的第一个号码,基本上停止会遇到不是数字的东西,我们突然也可以轻松地处理负数:

using System;
using System.Text.RegularExpression;

public static int ConvertToInt(String input)
{
    // Matches the first numebr with or without leading minus.
    Match match = Regex.Match(input, "-?[0-9]+");

    if (match.Success)
    {
        // No need to TryParse here, the match has to be at least
        // a 1-digit number.
        return int.Parse(match.Value);
    }

    return 0; // Or any other default value.
}

我们再次测试它:

"12ACD"  =>  12
"12A5"   =>  12
"CA12A"  =>  12
"-12AD"  =>  -12
""       =>  0
"AAAA"   =>  0

总的来说,如果我们谈论用户输入,我会考虑根本不接受无效输入,仅使用int.TryParse()而没有额外的魔法,并且在失败时通知用户输入不是最理想的(并且可能再次提示有效号码。)

答案 1 :(得分:15)

正则表达式是一种方法,demonstrated by Bobby

根据您的假设,另一种方法是以这种方式使用TakeWhile(使用TryParse以获得额外的安全性):

string input = "12ACD";
string digits = new string(input.TakeWhile(c => Char.IsDigit(c)).ToArray());
int result;
if (Int32.TryParse(digits, out result))
{
    Console.WriteLine(result);
}

当然,代码的目的不会立即弹出给读者,因为他们的大部分时间都用于解密被转换为TakeWhile的{​​{1}}部分。

答案 2 :(得分:3)

Bobby描述的正则表达式方法可能是解决这个问题的最佳方法,但如果你对正则表达式特别警惕,可以使用LINQ和Convert.ToInt32方法的组合:

    string test = "12ACD";
    int number = Convert.ToInt32(new String(test.Where(x => char.IsNumber(x)).ToArray()));

答案 3 :(得分:3)

使用Sprache

int t = Parse.Number.Select(int.Parse).Parse("12ACD");
print(t) //t should be 12 and type of int32.

答案 4 :(得分:0)

既然你知道你关心的唯一字符是前2个或只是第一个,你可以在前2个字符上使用int.TryParse和SubStringing。

如果返回false(即第二个字符不是数字),则只需对第一个字符进行int.Parse和Substring。

可能有一种更清洁的方式,但根据您的假设,这应该可以完成这项工作。

答案 5 :(得分:0)

即使CLI中存在这样的内在功能;您要么发现它仅适用于特定表格,要么必须告诉它表格和/或与表格一起使用的行为。换句话说,您希望解决方案与“AB123CD456EF”有什么关系?只解析第一次出现,将所有数字字符连接在一起并解析,或者将每个出现解析为可枚举结果的元素?

任何这些案例都通过正则表达式得到充分处理。我建议将您的解决方案广泛地整合到可读的,记录完备的函数中,无论您选择哪些好的建议。

答案 6 :(得分:0)

Ahmads解决方案让我想到这一点 - 假设字符串总是一个或两个数字,后跟至少一个非数字字符:

int number = Int32.Parse(
    Char.IsDigit(foo, 1)  ?  foo.Substring(0, 2)  :  foo.Substring(0, 1), 
    CultureInfo.InvariantCulture);

逻辑如下:如果索引1(位置2)处的字符是数字,则获取前两个字符,然后解析它们。如果索引1处的字符不是数字,则获取第一个字符,然后解析它。

答案 7 :(得分:0)

如何:

    public int ReadStartingNumber(string text)
    {
        if (string.IsNullOrEmpty(text) || !char.IsDigit(text[0]))
            throw new FormatException("Text does not start with any digits");

        int result = 0;
        foreach (var digit in text.TakeWhile(c => char.IsDigit(c)))
        {
            result = 10*result + (digit - '0');
        }

        return result;
    }

答案 8 :(得分:-1)

您可以使用RegEx.Match(正则表达式) 阅读关于他们的msdn文章。这很简单。

答案 9 :(得分:-1)

Int32.Parse()

其他数字类型也有等价物。

编辑:重读后,我看到你的字符串不仅仅是那个数字。在这种情况下,在使用解析之前,您需要先使用正则表达式拉出数字。

答案 10 :(得分:-1)

基于您的假设的最直接的代码如下......

string s = "13AD";
string s2 = s.Substring(0, s.Length - 2);
int i = int.Parse(s2);

如果您的假设得到保证,这是最可读的方式。不需要正则表达式或花哨的LINQ东西。 LINQ很棒,但它看起来经常被过度使用。