确定字符串是否为数字

Gol*_*old 688 c# string parsing isnumeric

如果我有这些字符串:

  1. "abc" = false

  2. "123" = true

  3. "ab2" = false

是否有一个命令,比如IsNumeric()或其他东西,可以识别字符串是否是有效数字?

mqp*_*mqp 1082

int n;
bool isNumeric = int.TryParse("123", out n);
Run Code Online (Sandbox Code Playgroud)

从C#7开始更新:

var isNumeric = int.TryParse("123", out int n);
Run Code Online (Sandbox Code Playgroud)

变种 S可通过它们各自的类型来代替!

  • 虽然,我会使用double.TryParse,因为我们想知道它是否代表一个数字. (120认同)
  • 这是一个很好的解决方案,直到用户输入超过-2,147,483,648到2,147,483,647的值,然后这默默地失败 (9认同)
  • 如果我将字符串作为"-123"或"+123"传递,函数将返回true.我理解整数有正负值.但如果此字符串来自用户输入的文本框,则它应返回false. (5认同)
  • 我更喜欢这个检查的扩展方法:`public static bool IsNumeric(this string text) { double _out; return double.TryParse(text, out _out); }` (3认同)
  • 对于最长的字符串,最好使用“long.TryParse”。例如“2082546844562”是一个数字,但不能解析为整数。 (2认同)

Joh*_*ant 350

如果input是所有数字,则返回true .不知道它是否比TryParse它好,但它会起作用.

Regex.IsMatch(input, @"^\d+$")
Run Code Online (Sandbox Code Playgroud)

如果你只是想知道它是否有一个或多个数字与字符混合,请不要使用^ +$.

Regex.IsMatch(input, @"\d")
Run Code Online (Sandbox Code Playgroud)

编辑: 实际上我认为它比TryParse更好,因为很长的字符串可能会溢出TryParse.

  • @MAXE:我不同意.正则表达式检查非常慢,因此如果考虑性能,通常会有更好的解决方案. (19认同)
  • 也会因为`.`而在负面和事情上失败 (7认同)
  • 编辑:你可以添加`RegexOptions.Compiled`作为参数,如果你运行成千上万的这些可能的速度增加`Regex.IsMatch(x.BinNumber,@"^\d + $",RegexOptions.Compiled)` (6认同)
  • 但是,一劳永逸地构建正则表达式会更有效率. (2认同)
  • @CFP +1 ... RegEx总是优于通常的功能,适用时! (2认同)
  • @Noctis,是的,但是如果您查看原始问题(尤其是在编辑之前),则 OP 似乎在寻找 *digits*,而不是真正的实际数字。这个简单的正则表达式无法解析许多有效数字是完全正确的。 (2认同)
  • 对于任何新手,您都需要添加:using System.Text.RegularExpressions; 在您的视觉工作室班级中 (2认同)

Kun*_*oel 186

您还可以使用:

stringTest.All(char.IsDigit);
Run Code Online (Sandbox Code Playgroud)

如果输入字符串是任何类型的字母数字,它将返回true所有数字数字(不是float)false.

请注意:stringTest不应该是空字符串,因为这会通过数字测试.

  • 那很酷.但有一点需要注意:空字符串会将该测试作为数字传递. (16认同)
  • 萨尔曼,这不是那么简单 - 这会将`.. - ..--`作为有效数字.显然不是. (4认同)
  • 这也不适用于小数情况。正确的测试是 stringTest.All(l => char.IsDigit(l) || '.' == l || '-' == l); (3认同)
  • @ dan-gph:我很高兴,你喜欢它.是的,你是对的.我已经更新了上面的说明.谢谢! (2认同)

Nel*_*nda 129

我已多次使用此功能:

public static bool IsNumeric(object Expression)
{
    double retNum;

    bool isNum = Double.TryParse(Convert.ToString(Expression), System.Globalization.NumberStyles.Any, System.Globalization.NumberFormatInfo.InvariantInfo, out retNum);
    return isNum;
}
Run Code Online (Sandbox Code Playgroud)

但你也可以使用;

bool b1 = Microsoft.VisualBasic.Information.IsNumeric("1"); //true
bool b2 = Microsoft.VisualBasic.Information.IsNumeric("1aa"); // false
Run Code Online (Sandbox Code Playgroud)

基准测试IsNumeric选项

替代文字http://aspalliance.com/images/articleimages/80/Figure1.gif

替代文字http://aspalliance.com/images/articleimages/80/Figure2.gif

  • 从C#app引用Microsoft.VisualBasic.dll?eww:P (78认同)
  • 好吧,VB.NET的IsNumeric()在内部使用了double.TryParse(),经过了许多需要(等等)的旋转以实现VB6的兼容性.如果您不需要兼容性,double.TryParse()就像使用一样简单,它可以通过在您的进程中加载​​Microsoft.VisualBasic.dll来避免浪费内存. (10认同)
  • 快速说明:如果您设法一劳永逸地构建基础有限状态机,那么使用正则表达式将会快得多.通常,构建状态机需要O(2 ^ n),其中n是正则表达式的长度,而读数是O(k),其中k是被搜索的字符串的长度.因此,每次重建正则表达式都会带来偏见. (4认同)
  • @Lucas实际上,那里有一些非常好的东西,比如一个完整的csv解析器.没有理由不使用它,如果它存在于那里. (2认同)

Eur*_*lli 32

这可能是C#中的最佳选择.

如果您想知道字符串是否包含整数(整数):

string someString;
// ...
int myInt;
bool isNumerical = int.TryParse(someString, out myInt);
Run Code Online (Sandbox Code Playgroud)

TryParse方法将尝试将字符串转换为数字(整数),如果成功,它将返回true并将相应的数字放在myInt中.如果不能,则返回false.

使用int.Parse(someString)其他响应中显示的替代方案的解决方案可行,但速度要慢得多,因为抛出异常非常昂贵.TryParse(...)在版本2中添加到C#语言,直到那时你没有选择.现在你做:你应该避免Parse()替代方案.

如果要接受十进制数,则十进制类也有一个.TryParse(...)方法.在上面的讨论中用int替换int,并且适用相同的原则.


The*_*TXI 25

对于许多数据类型,您始终可以使用内置的TryParse方法来查看相关字符串是否会通过.

例.

decimal myDec;
var Result = decimal.TryParse("123", out myDec);
Run Code Online (Sandbox Code Playgroud)

然后结果= True

decimal myDec;
var Result = decimal.TryParse("abc", out myDec);
Run Code Online (Sandbox Code Playgroud)

结果将= False


BFr*_*ree 20

如果您不想使用int.Parse或double.Parse,您可以使用以下内容滚动自己:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 1.3.3.8.5实际上不是一个数字,而1.23E5是. (11认同)
  • 如果他们只是意味着整数怎么办?那些'.'的语言环境怎么样?是组分隔符,而不是逗号(例如pt-Br)?负数怎么样?组分隔符(英文逗号)?货币符号?TryParse()可以使用NumberStyles和IFormatProvider根据需要管理所有这些. (6认同)
  • 逻辑是有缺陷的.-1 (4认同)
  • @Lucas 我同意 TryParse 处理更多,但有时不需要。我只需要验证我的信用卡号框(只能有数字)。这个解决方案几乎肯定比 try parse 快。 (2认同)

cyb*_*spy 14

我知道这是一个旧线程,但没有一个答案真的为我做了 - 要么效率低,要么没有封装以便于重用.如果字符串为空或null,我还想确保它返回false.在这种情况下,TryParse返回true(空字符串在解析为数字时不会导致错误).所以,这是我的字符串扩展方法:

public static class Extensions
{
    /// <summary>
    /// Returns true if string is numeric and not empty or null or whitespace.
    /// Determines if string is numeric by parsing as Double
    /// </summary>
    /// <param name="str"></param>
    /// <param name="style">Optional style - defaults to NumberStyles.Number (leading and trailing whitespace, leading and trailing sign, decimal point and thousands separator) </param>
    /// <param name="culture">Optional CultureInfo - defaults to InvariantCulture</param>
    /// <returns></returns>
    public static bool IsNumeric(this string str, NumberStyles style = NumberStyles.Number,
        CultureInfo culture = null)
    {
        double num;
        if (culture == null) culture = CultureInfo.InvariantCulture;
        return Double.TryParse(str, style, culture, out num) && !String.IsNullOrWhiteSpace(str);
    }
}
Run Code Online (Sandbox Code Playgroud)

使用简单:

var mystring = "1234.56789";
var test = mystring.IsNumeric();
Run Code Online (Sandbox Code Playgroud)

或者,如果要测试其他类型的数字,可以指定"样式".因此,要使用Exponent转换数字,您可以使用:

var mystring = "5.2453232E6";
var test = mystring.IsNumeric(style: NumberStyles.AllowExponent);
Run Code Online (Sandbox Code Playgroud)

或者要测试潜在的十六进制字符串,您可以使用:

var mystring = "0xF67AB2";
var test = mystring.IsNumeric(style: NumberStyles.HexNumber)
Run Code Online (Sandbox Code Playgroud)

可选的'culture'参数可以大致相同的方式使用.

由于无法转换太大而不能包含在double中的字符串而受到限制,但这是一个有限的要求,我认为如果您使用的数字大于此值,那么您可能需要额外的专用数字处理无论如何功能.

  • 除Double.TryParse不支持NumberStyles.HexNumber外,它的工作原理非常好。请参见MSDN Double.TryParse。为什么在检查IsNullOrWhiteSpace之前尝试TryParse?如果不是IsNullOrWhiteSpace,TryParse返回false吗? (2认同)

JDB*_*JDB 12

如果您想要捕获更广泛的数字,例如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 );
}
Run Code Online (Sandbox Code Playgroud)

单元测试:

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 );
}
Run Code Online (Sandbox Code Playgroud)

请记住,仅仅因为值是数字并不意味着它可以转换为数字类型.例如,"999999999999999999999999999999.9999999999"是一个perfeclty有效数值,但它不适合.NET数字类型(不是标准库中定义的那个).


Day*_*uiz 12

Kunal Noel 答案的更新

stringTest.All(char.IsDigit);
// This returns true if all characters of the string are digits.
Run Code Online (Sandbox Code Playgroud)

但是,对于这种情况,我们有空字符串将通过该测试,因此,您可以:

if (!string.IsNullOrEmpty(stringTest) && stringTest.All(char.IsDigit)){
   // Do your logic here
}
Run Code Online (Sandbox Code Playgroud)

  • 这是更好的答案,因为它实际上不会将字符串转换为整数并存在整数溢出的风险。 (3认同)

Cra*_*aig 9

您可以使用TryParse来确定字符串是否可以解析为整数.

int i;
bool bNum = int.TryParse(str, out i);
Run Code Online (Sandbox Code Playgroud)

布尔值会告诉你它是否有效.


Noc*_*tis 9

如果你想检查一个字符串是否是一个数字(我假设它是一个字符串,因为如果它是一个数字,呃,你知道它是一个).

  • 没有正则表达式和
  • 尽可能使用Microsoft的代码

你也可以这样做:

public static bool IsNumber(this string aNumber)
{
     BigInteger temp_big_int;
     var is_number = BigInteger.TryParse(aNumber, out temp_big_int);
     return is_number;
}
Run Code Online (Sandbox Code Playgroud)

这将照顾通常的恶意:

  • 开头减去( - )或加号(+)
  • 包含十进制字符BigIntegers不会解析带小数点的数字.(所以:BigInteger.Parse("3.3")会抛出异常,并且TryParse同样会返回false)
  • 没有搞笑的非数字
  • 涵盖数量大于通常使用数量的情况 Double.TryParse

你必须添加一个引用System.Numerics并且 using System.Numerics;在你的班级之上(好吧,第二个是我想的奖金:)


Hei*_*tad 8

我想这个答案只会在所有其他答案之间丢失,但无论如何,这里也是如此.

我通过谷歌结束了对这个问题,因为我想检查,如果stringnumeric这样我可以只使用double.Parse("123")了替代TryParse()方法.

为什么?因为在知道解析是否失败之前必须声明out变量并检查结果是很烦人的TryParse().我想使用的ternary operator检查,如果stringnumerical,然后就分析它在第一三元表达或提供第二三元表达式的默认值.

像这样:

var doubleValue = IsNumeric(numberAsString) ? double.Parse(numberAsString) : 0;
Run Code Online (Sandbox Code Playgroud)

它比以下更清洁:

var doubleValue = 0;
if (double.TryParse(numberAsString, out doubleValue)) {
    //whatever you want to do with doubleValue
}
Run Code Online (Sandbox Code Playgroud)

extension methods为这些案件做了一对:


扩展方法之一

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);
}
Run Code Online (Sandbox Code Playgroud)

例:

"123".IsParseableAs<double>() ? double.Parse(sNumber) : 0;
Run Code Online (Sandbox Code Playgroud)

因为IsParseableAs()尝试将字符串解析为适当的类型而不是仅仅检查字符串是否为"数字",所以它应该是非常安全的.您甚至可以将它用于具有TryParse()方法的非数字类型,例如DateTime.

该方法使用反射,你最终调用该TryParse()方法两次,当然,效率不高,但并不是所有东西都必须完全优化,有时方便更重要.

此方法还可用于轻松地将数字字符串列表解析为double具有默认值的列表或其他类型,而不必捕获任何异常:

var sNumbers = new[] {"10", "20", "30"};
var dValues = sNumbers.Select(s => s.IsParseableAs<double>() ? double.Parse(s) : 0);
Run Code Online (Sandbox Code Playgroud)

扩展方法二

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;
}
Run Code Online (Sandbox Code Playgroud)

此扩展方法允许您解析具有方法的string任何方法,并且还允许您指定在转换失败时返回的默认值.typeTryParse()

这比使用上面的扩展方法的三元运算符更好,因为它只进行一次转换.它仍然使用反射......

例子:

"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);
Run Code Online (Sandbox Code Playgroud)

输出:

123
25
123,78
107,4
28.10.2014 00:00:00
01.01.0001 00:00:00
Run Code Online (Sandbox Code Playgroud)

  • 你试过`var x = double.TryParse("2.2",new double())?double.Parse("2.2"):0.0;`? (5认同)
  • 我相信你可能已经发明了我见过的效率最低的方法之一.您不仅要解析字符串两次(在它是可解析的情况下),您还要多次调用*reflection*函数来执行此操作.而且,最后,您甚至不使用扩展方法保存任何击键. (4认同)
  • 感谢您重复我在倒数第二段中自己写的内容。另外,如果您考虑到我的最后一个示例,那么您肯定可以使用此扩展方法来节省击键次数。这个答案并不声称是任何问题的某种神奇解决方案,它只是一个代码示例。使用它,或者不使用它。我认为只要使用得当,它会很方便。并且包含了扩展方法和反射的例子,也许有人可以借鉴。 (2认同)
  • 是的,它不起作用.`参数2必须与'out'关键字一起传递,如果指定`out`和`new`,你得到`ref或out参数必须是一个可赋值变量`. (2认同)

Gab*_*rit 6

如果您想知道字符串是否为数字,您可以尝试解析它:

var numberString = "123";
int number;

int.TryParse(numberString , out number);
Run Code Online (Sandbox Code Playgroud)

请注意,TryParse返回a bool,您可以使用它来检查解析是否成功.


小智 6

Double.TryParse

bool Double.TryParse(string s, out double result)
Run Code Online (Sandbox Code Playgroud)


Lia*_*kat 5

.net 内置函数的最佳灵活解决方案称为- char.IsDigit。它适用于无限长的数字。如果每个字符都是数字,它只会返回 true。我多次使用它,没有任何问题,而且我找到的解决方案更容易清洁。我做了一个示例方法。它可以使用了。此外,我添加了对 null 和空输入的验证。所以这个方法现在是完全防弹的

public static bool IsNumeric(string strNumber)
    {
        if (string.IsNullOrEmpty(strNumber))
        {
            return false;
        }
        else
        {
            int numberOfChar = strNumber.Count();
            if (numberOfChar > 0)
            {
                bool r = strNumber.All(char.IsDigit);
                return r;
            }
            else
            {
                return false;
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)


小智 5

试试下面的reges

new Regex(@"^\d{4}").IsMatch("6")    // false
new Regex(@"^\d{4}").IsMatch("68ab") // false
new Regex(@"^\d{4}").IsMatch("1111abcdefg")
new Regex(@"^\d+").IsMatch("6") // true (any length but at least one digit)
Run Code Online (Sandbox Code Playgroud)