如果我有这些字符串:
"abc" =假 "123" =真 "ab2" = false
是否有一个命令,如IsNumeric()或其他命令,可以识别字符串是否是有效的数字?
如果我有这些字符串:
"abc" =假 "123" =真 "ab2" = false
是否有一个命令,如IsNumeric()或其他命令,可以识别字符串是否是有效的数字?
当前回答
在项目中导入Visual Basic引用并使用其信息。IsNumeric方法,如下所示,并且能够捕获浮点数以及整数,不像上面的答案只捕获int。
// Using Microsoft.VisualBasic;
var txt = "ABCDEFG";
if (Information.IsNumeric(txt))
Console.WriteLine ("Numeric");
IsNumeric("12.3"); // true
IsNumeric("1"); // true
IsNumeric("abc"); // false
其他回答
我猜这个答案会被淹没在其他答案中,但不管怎样,开始吧。
我最终通过谷歌解决了这个问题,因为我想检查字符串是否为数字,这样我就可以使用double.Parse(“123”)而不是TryParse()方法。
为什么?因为在知道解析是否失败之前,必须声明一个out变量并检查TryParse()的结果是很烦人的。我想使用三元运算符来检查字符串是否为数值,然后在第一个三元表达式中解析它或在第二个三元表达式中提供默认值。
是这样的:
var doubleValue = IsNumeric(numberAsString) ? double.Parse(numberAsString) : 0;
它只是比:
var doubleValue = 0;
if (double.TryParse(numberAsString, out doubleValue)) {
//whatever you want to do with doubleValue
}
我为这些情况做了一些扩展方法:
可拓方法一
public static bool IsParseableAs<TInput>(this string value) {
var type = typeof(TInput);
var tryParseMethod = type.GetMethod("TryParse", BindingFlags.Static | BindingFlags.Public, Type.DefaultBinder,
new[] { typeof(string), type.MakeByRefType() }, null);
if (tryParseMethod == null) return false;
var arguments = new[] { value, Activator.CreateInstance(type) };
return (bool) tryParseMethod.Invoke(null, arguments);
}
例子:
"123".IsParseableAs<double>() ? double.Parse(sNumber) : 0;
因为IsParseableAs()尝试将字符串解析为适当的类型,而不仅仅是检查字符串是否为“numeric”,所以应该是相当安全的。您甚至可以将它用于具有TryParse()方法的非数值类型,如DateTime。
该方法使用反射,最终调用TryParse()方法两次,当然,这不是那么有效,但并不是所有事情都必须完全优化,有时方便更重要。
此方法还可以用于轻松地将数字字符串列表解析为具有默认值的double或其他类型的列表,而无需捕获任何异常:
var sNumbers = new[] {"10", "20", "30"};
var dValues = sNumbers.Select(s => s.IsParseableAs<double>() ? double.Parse(s) : 0);
可拓方法二
public static TOutput ParseAs<TOutput>(this string value, TOutput defaultValue) {
var type = typeof(TOutput);
var tryParseMethod = type.GetMethod("TryParse", BindingFlags.Static | BindingFlags.Public, Type.DefaultBinder,
new[] { typeof(string), type.MakeByRefType() }, null);
if (tryParseMethod == null) return defaultValue;
var arguments = new object[] { value, null };
return ((bool) tryParseMethod.Invoke(null, arguments)) ? (TOutput) arguments[1] : defaultValue;
}
这个扩展方法允许您将字符串解析为具有TryParse()方法的任何类型,它还允许您指定转换失败时要返回的默认值。
这比上面的扩展方法使用三元运算符要好,因为它只进行一次转换。它仍然使用反射…
例子:
"123".ParseAs<int>(10);
"abc".ParseAs<int>(25);
"123,78".ParseAs<double>(10);
"abc".ParseAs<double>(107.4);
"2014-10-28".ParseAs<DateTime>(DateTime.MinValue);
"monday".ParseAs<DateTime>(DateTime.MinValue);
输出:
123
25
123,78
107,4
28.10.2014 00:00:00
01.01.0001 00:00:00
你还可以使用:
using System.Linq;
stringTest.All(char.IsDigit);
它将返回true对于所有数字(不是浮点)和false如果输入字符串是任何类型的字母数字。
Test case | Return value | Test result |
---|---|---|
"1234" |
true | ✅Pass |
"1" |
true | ✅Pass |
"0" |
true | ✅Pass |
"" |
true | ⚠️Fail (known edge case) |
"12.34" |
false | ✅Pass |
"+1234" |
false | ✅Pass |
"-13" |
false | ✅Pass |
"3E14" |
false | ✅Pass |
"0x10" |
false | ✅Pass |
请注意:stringTest不应该是空字符串,因为这将通过是否是数字的测试。
以防你不想用int。解析或双重。解析,你可以用这样的东西来滚动你自己的:
public static class Extensions
{
public static bool IsNumeric(this string s)
{
foreach (char c in s)
{
if (!char.IsDigit(c) && c != '.')
{
return false;
}
}
return true;
}
}
bool is_number(string str, char delimiter = '.')
{
if(str.Length==0) //Empty
{
return false;
}
bool is_delimetered = false;
foreach (char c in str)
{
if ((c < '0' || c > '9') && (c != delimiter)) //ASCII table check. Not a digit && not delimeter
{
return false;
}
if (c == delimiter)
{
if (is_delimetered) //more than 1 delimiter
{
return false;
}
else //first time delimiter
{
is_delimetered = true;
}
}
}
return true;
}
如果你想捕获更广泛的数字,à la PHP的is_numeric,你可以使用以下方法:
// From PHP documentation for is_numeric
// (http://php.net/manual/en/function.is-numeric.php)
// Finds whether the given variable is numeric.
// Numeric strings consist of optional sign, any number of digits, optional decimal part and optional
// exponential part. Thus +0123.45e6 is a valid numeric value.
// Hexadecimal (e.g. 0xf4c3b00c), Binary (e.g. 0b10100111001), Octal (e.g. 0777) notation is allowed too but
// only without sign, decimal and exponential part.
static readonly Regex _isNumericRegex =
new Regex( "^(" +
/*Hex*/ @"0x[0-9a-f]+" + "|" +
/*Bin*/ @"0b[01]+" + "|" +
/*Oct*/ @"0[0-7]*" + "|" +
/*Dec*/ @"((?!0)|[-+]|(?=0+\.))(\d*\.)?\d+(e\d+)?" +
")$" );
static bool IsNumeric( string value )
{
return _isNumericRegex.IsMatch( value );
}
单元测试:
static void IsNumericTest()
{
string[] l_unitTests = new string[] {
"123", /* TRUE */
"abc", /* FALSE */
"12.3", /* TRUE */
"+12.3", /* TRUE */
"-12.3", /* TRUE */
"1.23e2", /* TRUE */
"-1e23", /* TRUE */
"1.2ef", /* FALSE */
"0x0", /* TRUE */
"0xfff", /* TRUE */
"0xf1f", /* TRUE */
"0xf1g", /* FALSE */
"0123", /* TRUE */
"0999", /* FALSE (not octal) */
"+0999", /* TRUE (forced decimal) */
"0b0101", /* TRUE */
"0b0102" /* FALSE */
};
foreach ( string l_unitTest in l_unitTests )
Console.WriteLine( l_unitTest + " => " + IsNumeric( l_unitTest ).ToString() );
Console.ReadKey( true );
}
请记住,仅仅因为值是数字类型并不意味着它可以转换为数字类型。例如,“999999999999999999999999999999999999999999999999”是一个完全有效的数值,但它不适合. net数值类型(也就是说,不是标准库中定义的数值类型)。