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

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

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

一些假设是

  1. 字符串模式始终是数字后跟字符。
  2. 数字部分始终为一位或两位数值。

是否有任何C#预定义函数来解析字符串中的数值?

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

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

对于12ABC ,此函数将产生12 ,因此如果您需要能够处理负数,则需要一个不同的解决方案。 它也不安全,如果只传递非数字,它将产生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()而没有一些额外的魔法,并且在失败时通知用户输入是次优的(并且可能再次提示输入有效数)。

正如Bobby所展示的那样 ,正则表达式是一种方法。

根据您的假设,另一种方法TakeWhile这种方式使用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); } 

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

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

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

使用Sprache :

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

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

如果返回false(即第二个char不是数字),那么只需对第一个char执行int.Parse和Substring。

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

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

Int32.Parse()

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

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

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

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

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

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

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

怎么样:

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

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

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

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