C# 从非数字之间的字符串中解析数字
我正在处理.NET项目,我试图只解析字符串中的数值。比如说,C# 从非数字之间的字符串中解析数字,c#,C#,我正在处理.NET项目,我试图只解析字符串中的数值。比如说, string s = "12ACD"; int t = someparefun(s); print(t) //t should be 12 有几个假设是正确的 字符串模式始终是数字后跟字符 数字部分始终为一位或两位数字值 是否有任何C#预定义函数来解析字符串中的数值?您可以使用RegEx.Match(正则表达式) 阅读msdn关于它们的文章。这很简单。没有这样的函数,至少我知道没有。但有一种方法是使用正则表达式删除所有不是数字的内
string s = "12ACD";
int t = someparefun(s);
print(t) //t should be 12
有几个假设是正确的
阅读msdn关于它们的文章。这很简单。没有这样的函数,至少我知道没有。但有一种方法是使用正则表达式删除所有不是数字的内容:
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
,因此如果您需要能够处理负数,则需要另一种解决方案。它也是不安全的,如果只传递非数字,则会产生格式异常
。以下是一些示例数据:
"12ACD" => 12
"12A5" => 125
"CA12A" => 12
"-12AD" => 12
"" => FormatException
"AAAA" => FormatException
更详细但更安全的方法是使用:
下面是一些示例数据:
"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 .TyPARSESER()/<代码>而不需要额外的魔法,并且在失败时通知用户输入是次优的(并且可能再次提示一个有效的数字)。
还有其他数字类型的等价物
编辑:重读之后,我发现你的字符串不仅仅是那个数字。在这种情况下,在使用parse之前,您需要先用正则表达式取出数字。因为您知道您关心的唯一字符是前2个或仅是前2个,所以可以在前2个字符上使用int.TryParse和substring 如果返回false(即第二个字符不是数字),则只需对第一个字符执行int.Parse和Substring 可能有一种更干净的方法,但基于您的假设,它应该可以完成这项工作。Regex是一种方法,如图所示 根据您的假设,另一种方法是以这种方式使用(使用
TryParse
以获得额外的安全性):
当然,代码的用途不会立即显示给读者,因为他们的大部分时间都花在破译
TakeWhile
部分,而部分被转换成字符串Bobby描述的正则表达式方法可能是处理这一问题的最佳方法,但如果您特别小心正则表达式,则可以使用它LINQ和Convert.ToInt32方法的组合:
string test = "12ACD";
int number = Convert.ToInt32(new String(test.Where(x => char.IsNumber(x)).ToArray()));
基于您的假设,最直接的代码如下
string s = "13AD";
string s2 = s.Substring(0, s.Length - 2);
int i = int.Parse(s2);
如果你的假设是有保证的,这是最可读的方法。不需要regex或别致的LINQ。LINQ很好,但它似乎被过度使用了。即使CLI中有这样一个内在函数;您可能会发现它只在特定的表单上起作用,或者必须告诉它要与所述表单一起使用的表单和/或行为。换句话说,您希望您的解决方案如何处理“AB123CD456EF”?只解析第一个匹配项,将所有数字字符连接在一起并进行解析,还是将每个匹配项解析为可枚举结果的一个元素
这些情况中的任何一种都可以通过正则表达式得到充分的处理。我建议将您的解决方案广泛地包装到可读的、有良好文档记录的函数中,无论您从已经给出的好建议中选择哪一个。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;
}
使用:
鲁宾逊会有危险的!危险!前面是正则表达式!毁灭!毁灭@兰多普洛:我知道,我知道……我知道他现在有两个问题,但都不是我的问题;p由于string
实现了IEnumerable
,因此不需要调用ToCharray
。另外,我可能会选择TakeWhile
而不是Where
,这样,例如,“12ACD3”就不会变成“123”。但这显然需要指定。@Dan Tao-我听说字符串实现IEnumerable,但由于intellisense在我的VS2008副本中没有给我这个选项,我不确定它是否能工作。刚测试过,编译的不错,所以我编辑了我的答案。为这些信息干杯,只是想表明你不能总是相信你的工具。许多人使用ToCharArray
来强制它以IntelliSense的形式出现,但它没有它也能工作。您可能还对这篇文章感兴趣:为什么VS2008不在Intellisense中为String类()显示扩展方法代码>?不过,如果只有一个数字,它也不会起作用。(对于上面的代码,“12ACD”将失败,因为s.Length-2
是3
并且12A
不能解析为Int32。)由于格式问题,我误读了这个问题。他有一个列表,但它的格式不是这样的。我认为他有1或2个字符,后面紧跟着2个字符,因为2个列表项看起来不像列表项。事实上,他有任意的字符,所以regex选项(目前投票最多)可能是最好的,正如答案的海报敏锐地指出的那样代码>不足,因为他可以有一个或两个数字。这部分不保证。如果您将TakeWhile调用封装到一个额外的GetStartingDigits函数中,代码应该很容易阅读。为什么要将Int32.TryParse
int括起来
int number = Int32.Parse(
Char.IsDigit(foo, 1) ? foo.Substring(0, 2) : foo.Substring(0, 1),
CultureInfo.InvariantCulture);
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;
}
int t = Parse.Number.Select(int.Parse).Parse("12ACD");
print(t) //t should be 12 and type of int32.