我正在处理.NET项目,我试图从字符串中解析数字值。例如,从一个非数字字符串中解析数字
string s = "12ACD";
int t = someparefun(s);
print(t) //t should be 12
一对夫妇的假设是
- 的字符串模式将永远是由字符数如下。
- 数字部分始终是一个或两个数字值。
是否有任何C#预定义函数来解析字符串的数值?
我正在处理.NET项目,我试图从字符串中解析数字值。例如,从一个非数字字符串中解析数字
string s = "12ACD";
int t = someparefun(s);
print(t) //t should be 12
一对夫妇的假设是
是否有任何C#预定义函数来解析字符串的数值?
有没有这样的功能,至少我没有知道。但是,一个方法是使用正则表达式来删除一切,是不是数字:
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()
没有一些额外的魔法并在失败时通知用户输入不理想(并可能再次提示输入有效数字)。
您可以使用RegEx.Match(正则表达式) 阅读他们的MSDN文章。很简单。
既然你知道你关心的唯一字符是前2或只是第一个,你可以在前2个字符上使用int.TryParse和SubStringing。
如果返回false(即第二个字符不是数字),那么只需在第一个字符上执行int.Parse和Substring。
有可能是一种更干净的方式,但根据您的假设,应该完成这项工作。
正则表达式是一种方法,如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
部分,转换为string
。
如果将TakeWhile调用封装到一个额外的GetStartingDigits函数中,则应该很容易通读代码。 – 2010-07-08 15:25:59
为什么你将'Int32.TryParse'放入if?如果解析失败,原始的“结果”将保持不变。此外,你不应该使用try catch吗?因此内置函数'TryParse'?如果你使用'.Parse',那么这是有道理的。仍然是非常有用的代码。谢谢 – ppumkin 2014-02-13 20:50:02
@ppumkin'TryParse'用于避免显式的try/catch。因为它返回一个布尔值,所以我把它放在一个'if'中,所以通过使用它,你马上知道解析是否成功,并且可以继续使用'result'。如果你不想在解析尝试失败时依赖默认的'result',那么这会给你更多的控制权。这取决于场景。如果我选择使用'int.Parse',我会使用try/catch。同样的想法,但'TryParse'给了我们更可读性和避免额外的工作。感谢您的评论! – 2014-02-13 20:59:45
由鲍比描述的正则表达式的方法可能是处理这种最好的方式,但如果你是特别警惕的正则表达式,你可以使用LINQ的组合和Convert.ToInt32方法:
string test = "12ACD";
int number = Convert.ToInt32(new String(test.Where(x => char.IsNumber(x)).ToArray()));
'ToCharArray'调用是不必要的,因为'string'实现了'IEnumerable
@丹涛 - 我听说字符串实现IEnumerable
很多人使用'ToCharArray'来强制它在IntelliSense中显示,但它没有它。您可能也对这篇文章感兴趣:为什么VS 2008不在Intellisense中为String类显示扩展方法(http://stackoverflow.com/questions/345883/why-doesnt-vs-2008-display-extension-methods-在-智能感知换串级)。 – 2010-07-08 15:39:37
的根据您的假设,最直接的代码将如下所示...
string s = "13AD";
string s2 = s.Substring(0, s.Length - 2);
int i = int.Parse(s2);
如果您的假设得到保证,这是最可行的方法。无需正则表达式或花哨的LINQ的东西。 LINQ很棒,但它似乎过于频繁地使用过。
你是不是指's.substring(0,2);'?但是,如果只有一位数字,它将不起作用。 (使用上面的代码,“12ACD”会失败,因为's.Length-2'为'3','12A'不能解析为Int32。) – sunside 2010-07-08 15:20:06
由于格式化,我误解了这个问题。他有一个列表,但没有格式化。我以为他有1或2个字符后跟正好2个字符,因为2列表项不看起来像列表项。事实上,他的字符数是任意的,所以正则表达式选项(当前最高的投票数)可能是最好的,正如答案的海报中明确指出的那样。 – 2010-07-08 21:06:22
哦,'Substring(0,2);'是不够的,因为他可以有一个或两个数字。这部分不能保证。 – 2010-07-08 21:06:52
即使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;
}
可读性的代价非常低,您也可以简单地在经典的“i”中使用普通循环,并在第一个非数字处打破。 – 2010-07-08 15:38:34
使用Sprache:
int t = Parse.Number.Select(int.Parse).Parse("12ACD");
print(t) //t should be 12 and type of int32.
的可能的复制[查找并从字符串中提取一些(http://stackoverflow.com/questions/4734116/查找和提取一个字符串中的数字) – 2016-08-08 06:43:01