识别字符串是否为数字


730

如果我有这些字符串:

  1. "abc" = false

  2. "123" = true

  3. "ab2" = false

是否有类似命令IsNumeric()或其他命令可以识别字符串是否为有效数字?


79
从他们的示例中,您可以看到它们意味着整个字符串是否代表一个数字。
卢卡斯,

47
返回str.All(Char.IsDigit);
Mohsen 2013年

13
str.All(Char.IsDigit)将声明“ 3.14”为false以及为“ -2”和“ 3E14”。
更不用说

4
这取决于您要检查的号码类型。对于不带分隔符的整数(即十进制数字的字符串),此检查有效,并且与接受的答案和OP中隐含的答案相同。
亚历克斯·马扎里奥尔

1
@Lucas谢谢您的评论,您不知道我已经尝试将字符串double解析为int并想知道为什么它失败了多
长时间

Answers:


1159
int n;
bool isNumeric = int.TryParse("123", out n);

从C#7开始更新

var isNumeric = int.TryParse("123", out int n);

或者如果您不需要数字,则可以放弃 out参数

var isNumeric = int.TryParse("123", out _);

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


126
但是,我将使用double.TryParse,因为我们想知道它是否完全代表一个数字。
约翰·吉岑

5
如果我将字符串传递为“ -123”或“ +123”,则函数将返回true。我了解整数具有正值和负值。但是,如果此字符串来自用户输入的文本框,则应返回false。
user2323308 2013年

9
这是一个很好的解决方案,直到用户输入的值超出-2,147,483,648到2,147,483,647,然后它默默地失败了
BlackTigerX 2014年

尝试解析0,60(即逗号!),它是无效数字,但将解析为60!
Paul Zahra

2
我更喜欢使用此检查的扩展方法: public static bool IsNumeric(this string text) { double _out; return double.TryParse(text, out _out); }
Hamid Naeemi

350

如果input是所有数字,则将返回true 。不知道它是否比更好TryParse,但是它可以工作。

Regex.IsMatch(input, @"^\d+$")

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

Regex.IsMatch(input, @"\d")

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


2
但是,一劳永逸地构建正则表达式会更有效率。
–Clément

2
如果适用,@ CFP +1 ... RegEx总是比通常的功能更好!
MAXE 2012年

19
@MAXE:我不同意。正则表达式检查非常慢,因此如果考虑性能,通常会有更好的解决方案。
Michal B.

7
编辑:RegexOptions.Compiled如果要运行数千个参数以增加速度,则可以将其添加为参数Regex.IsMatch(x.BinNumber, @"^\d+$", RegexOptions.Compiled)
Simon_Weaver 2013年

9
也将失败底片和事情.
Noctis

199

您还可以使用:

stringTest.All(char.IsDigit);

如果输入字符串是任何字母数字形式,它将返回true所有数字位数(不是floatfalse

请注意stringTest不能为空字符串,因为这将通过数字测试。


20
太酷了。但是需要注意的一件事:空字符串将通过数字测试。
dan-gph 2015年

2
@ dan-gph:很高兴,你喜欢它。是的,你是对的。我已经更新了上面的注释。谢谢!
2015年

1
这对于十进制情况也不起作用。正确的测试将是stringTest.All(l => char.IsDigit(l)||'。'== l ||'-'== l);
Salman Hasrat Khan

感谢您的输入Salman,要专门检查字符串中的十进制,可以使用-if(Decimal.TryParse(stringTest2,out value)){/ *是,十进制/} else {/否,不是十进制* / }
Kunal Goel

6
萨尔曼(Salman),并不是那么简单-它可以..--..--作为有效数字传递。显然不是。
Flynn1179 '16

133

我已经多次使用此功能:

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

但是您也可以使用;

bool b1 = Microsoft.VisualBasic.Information.IsNumeric("1"); //true
bool b2 = Microsoft.VisualBasic.Information.IsNumeric("1aa"); // false

基准化IsNumeric选项

替代文字
(来源:aspalliance.com

替代文字
(来源:aspalliance.com


80
从C#应用程序引用Microsoft.VisualBasic.dll?eww:P
卢卡斯

使用“ IsNumeric”它没有问题,我没有问题。您还可以看到TryParse和IsNumeric之间的效率差异不大。请记住,TryParse在2.0中是新功能,在此之前,最好使用IsNumeric而不是其他任何策略。
尼尔森·米兰达

10
好吧,在为实现VB6兼容性而需要(尤其是)许多旋转之后,VB.NET的IsNumeric()内部使用double.TryParse()。如果不需要兼容性,可以使用double.TryParse()一样简单,它可以通过在进程中加载​​Microsoft.VisualBasic.dll来避免浪费内存。
Euro Micelli

4
快速说明:如果您能够一劳永逸地构建底层有限状态机,则使用正则表达式的速度会更快。通常,构建状态机需要O(2 ^ n),其中n是正则表达式的长度,而读取是O(k),其中k是要搜索的字符串的长度。因此,每次重建正则表达式都会产生偏差。
–Clément

2
@Lucas实际上,里面有一些非常不错的东西,例如完整的csv解析器。没有理由不使用它。
Nyerguds '16

32

这可能是C#中最好的选择。

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

string someString;
// ...
int myInt;
bool isNumerical = int.TryParse(someString, out myInt);

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

使用int.Parse(someString)其他响应中显示的替代方案的解决方案有效,但是它要慢得多,因为引发异常非常昂贵。TryParse(...)是在版本2中添加到C#语言中的,直到那时您别无选择。现在您要做:因此您应该避免Parse()其他选择。

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


为什么TryParse比将所有字符与整数字符更好?
Arjang

25

您始终可以对许多数据类型使用内置的TryParse方法,以查看所讨论的字符串是否可以通过。

例。

decimal myDec;
var Result = decimal.TryParse("123", out myDec);

结果将是= True

decimal myDec;
var Result = decimal.TryParse("abc", out myDec);

结果将为False


我想我可能在VB样式语法中比C#做得更多,但是适用相同的规则。
TheTXI

21

如果您不想使用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;
    }
}

7
如果它们仅表示整数怎么办?那'。'的语言环境呢?是组分隔符,而不是逗号(例如pt-Br)吗?那负数呢?组分隔符(英文逗号)?货币符号?TryParse()可以根据需要使用NumberStyles和IFormatProvider管理所有这些。
卢卡斯,

哦,是的,我更喜欢All版本。我从未真正使用过这种扩展方法,很好的调用。虽然应该是s.ToCharArray()。All(..)。关于您的第二点,我听到了,这就是为什么如果您不想使用int.Parse ....(我认为这会有更多开销...)作为我的
序言

11
1.3.3.8.5并不是一个真正的数字,而1.23E5是。
–Clément

4
逻辑有缺陷。-1
罗素·杨

1
@Lucas我同意TryParse可以处理更多内容,但有时并不需要。我只需要验证我的信用卡号码盒(只能有数字)。这个解决方案几乎肯定比尝试解析要快。
米莉·史密斯

14

如果您想获取更广泛的数字,例如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 );
}

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


这里不尝试成为聪明的专家,但是对于字符串“ 0”来说似乎失败了。我的正则表达式不存在。有一个简单的调整吗?我得到“ 0”,可能是“ 0.0”,甚至是“ -0.0”,这是可能的有效数字。
史蒂夫·希伯特

@SteveHibbert-每个人都知道“ 0”不是数字!说正经的......调整正则表达式匹配0
加多宝还记得莫妮卡

嗯,是我还是“ 0”仍不被识别为数字?
史蒂夫·希伯特

1
由于懒惰,并且对正则表达式不了解,所以我剪切了上面的代码,看起来其中包括了“ 0.0”类型更改。我进行了一项测试,以检查运行.IsNumeric()的字符串“ 0”是否返回false。我认为八进制测试将对具有两个数字字符的任何内容返回true,第一个为零(第二个为零至七个),但对于一个单独的大胖子零将返回false。如果使用上面的代码测试“ 0”,您是否会得到假?抱歉,如果我了解更多正则表达式,我将能够提供更好的反馈。必须阅读。
史蒂夫·希伯特

1
Do!只是重新阅读了上面的评论,我错过了额外的星号,我只更新了小数点。正确设置后,您说对了,“ 0”是数字。很抱歉,也非常感谢您的更新,希望它也能帮助其他人。多谢。
史蒂夫·希伯特

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

使用简单:

var mystring = "1234.56789";
var test = mystring.IsNumeric();

或者,如果要测试其他类型的数字,则可以指定“样式”。因此,要使用指数转换数字,可以使用:

var mystring = "5.2453232E6";
var test = mystring.IsNumeric(style: NumberStyles.AllowExponent);

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

var mystring = "0xF67AB2";
var test = mystring.IsNumeric(style: NumberStyles.HexNumber)

可选的“ culture”参数可以以几乎相同的方式使用。

它的局限性在于无法转换太大而不能包含在双精度数中的字符串,但这是一个有限的要求,我想如果您要使用大于此的数字,则可能需要其他专门的数字处理反正功能。


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

10

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

int i;
bool bNum = int.TryParse(str, out i);

布尔值会告诉您是否有效。


9

如果要检查字符串是否是数字(我假设它是字符串,因为如果是数字,,,您知道它是一个)。

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

您也可以这样做:

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

这将解决通常的情况:

  • 开头为减号(-)或加号(+)
  • 包含十进制字符BigIntegers不会解析带小数点的数字。(因此:BigInteger.Parse("3.3")将引发异常,并且TryParse同样会返回false)
  • 没有有趣的非数字
  • 涵盖数字大于通常用法的情况 Double.TryParse

您必须添加一个参考,System.Numerics using System.Numerics;在您的课堂上占上风(嗯,第二个是我猜想的奖励:)


8

我猜这个答案只会在其他所有答案之间迷失,但是无论如何,这是可行的。

我最终通过Google提出了这个问题,因为我想检查a是否是stringnumeric以便我可以使用double.Parse("123")而不是TryParse()方法。

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

像这样:

var doubleValue = IsNumeric(numberAsString) ? double.Parse(numberAsString) : 0;

它比:

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

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

例:

"123".IsParseableAs<double>() ? double.Parse(sNumber) : 0;

因为IsParseableAs()尝试将字符串解析为适当的类型,而不是仅仅检查字符串是否为“数字”,所以它应该非常安全。您甚至可以将其用于具有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;
}

此扩展方法使您可以将a解析stringtype具有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

4
我相信您可能已经发明了我见过的最无效的方法之一。您不仅要对字符串进行两次解析(在可解析的情况下),而且还要多次调用反射函数来执行此操作。最后,您甚至没有使用扩展方法保存任何击键。
JDB仍记得Monica

感谢您重复我在倒数第二段中写的内容。同样,如果考虑到我的最后一个示例,则肯定使用此扩展方法来保存击键。这个答案并不能说是解决任何问题的灵丹妙药,它仅仅是一个代码示例。使用它,或者不使用它。我认为正确使用起来很方便。它包括扩展方法和反射的示例,也许有人可以从中学习。
Hein AndreGrønnestad2014年

5
你试过了var x = double.TryParse("2.2", new double()) ? double.Parse("2.2") : 0.0;吗?
JDB仍然记得莫妮卡

2
是的,它不起作用。Argument 2 must be passed with the 'out' keyword并且如果您指定out以及new得到A ref or out argument must be an assignable variable
Hein AndreGrønnestad2015年

1
性能 TryParse优于这里公开的所有内容。结果:TryParse 8正则表达式20 PHP IsNumeric 30反射TryParse 31测试代码dotnetfiddle.net/x8GjAF
prampe

7

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

var numberString = "123";
int number;

int.TryParse(numberString , out number);

请注意,TryParse返回bool,可以用来检查解析是否成功。



4

更新Kunal Noel答案

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

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

if (!string.IsNullOrEmpty(stringTest) && stringTest.All(char.IsDigit)){
   // Do your logic here
}

4

带有.net内置功能的最佳灵活解决方案- char.IsDigit。它可以使用无限长数字。仅当每个字符都是数字时才返回true。我使用它很多次,没有问题,而且找到的解决方案也更容易。我做了一个示例方法,可以使用了。另外,我添加了对空和空输入的验证。所以现在该方法是完全防弹的

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


2

使用这些扩展方法可以清楚地区分字符串是否为数字和字符串是否包含0-9位数字

public static class ExtensionMethods
{
    /// <summary>
    /// Returns true if string could represent a valid number, including decimals and local culture symbols
    /// </summary>
    public static bool IsNumeric(this string s)
    {
        decimal d;
        return decimal.TryParse(s, System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.CurrentCulture, out d);
    }

    /// <summary>
    /// Returns true only if string is wholy comprised of numerical digits
    /// </summary>
    public static bool IsNumbersOnly(this string s)
    {
        if (s == null || s == string.Empty)
            return false;

        foreach (char c in s)
        {
            if (c < '0' || c > '9') // Avoid using .IsDigit or .IsNumeric as they will return true for other characters
                return false;
        }

        return true;
    }
}

2
public static bool IsNumeric(this string input)
{
    int n;
    if (!string.IsNullOrEmpty(input)) //.Replace('.',null).Replace(',',null)
    {
        foreach (var i in input)
        {
            if (!int.TryParse(i.ToString(), out n))
            {
                return false;
            }

        }
        return true;
    }
    return false;
}

1

希望这可以帮助

string myString = "abc";
double num;
bool isNumber = double.TryParse(myString , out num);

if isNumber 
{
//string is number
}
else
{
//string is not a number
}

0

在您的项目中引入对Visual Basic的引用,并使用其Information.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

这种方法的潜在问题是IsNumeric对字符串进行字符分析。因此,即使无法使用标准数字类型表示此数字,也9999999999999999999999999999999999999999999999999999999999.99999999999将像这样的数字注册为True
JDB仍记得Monica

0

试试下面的方法

new Regex(@"^\d{4}").IsMatch("6")    // false
new Regex(@"^\d{4}").IsMatch("68ab") // false
new Regex(@"^\d{4}").IsMatch("1111abcdefg") ```

0

所有的答案都是有用的。但是,当寻找数值等于或大于12位的解决方案时(在我的情况下),然后在调试时,我发现以下解决方案很有用:

double tempInt = 0;
bool result = double.TryParse("Your_12_Digit_Or_more_StringValue", out tempInt);

结果变量将为您提供true或false。



-7
//To my knowledge I did this in a simple way
static void Main(string[] args)
{
    string a, b;
    int f1, f2, x, y;
    Console.WriteLine("Enter two inputs");
    a = Convert.ToString(Console.ReadLine());
    b = Console.ReadLine();
    f1 = find(a);
    f2 = find(b);

    if (f1 == 0 && f2 == 0)
    {
        x = Convert.ToInt32(a);
        y = Convert.ToInt32(b);
        Console.WriteLine("Two inputs r number \n so that addition of these text box is= " + (x + y).ToString());
    }
    else
        Console.WriteLine("One or two inputs r string \n so that concatenation of these text box is = " + (a + b));
    Console.ReadKey();
}

static int find(string s)
{
    string s1 = "";
    int f;
    for (int i = 0; i < s.Length; i++)
       for (int j = 0; j <= 9; j++)
       {
           string c = j.ToString();
           if (c[0] == s[i])
           {
               s1 += c[0];
           }
       }

    if (s == s1)
        f = 0;
    else
        f = 1;

    return f;
}

1
四张赞成票,但没有人说为什么?我认为这是因为TryParse / Parse将是一个更好的选择,但并不是每个人都知道这一点。
njplumridge

2
您使它变得如此复杂,以至于C程序员甚至都会说“天哪,必须有一种更简单的方法来写它”
Ch3shire

1.没有理由从控制台读取两个号码并添加它们。无论如何,字符串的来源都是无关紧要的,因此根本没有理由从控制台读取任何内容。
Algoman

2. f的变量是不必要的,您可以直接返回0或1-如果要单次返回,则可以使用三元运算符。int也是错误的返回类型,应该是bool,您可以返回s == s1
Algoman

3.将s的数字复制到s1,然后将s与s1比较。这比需要的要慢得多。另外,即使c [0] == s [i]发生了,为什么还要继续执行内部循环?您是否期望s [i]也等于其他数字?
Algoman
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.