在Dart中检查字符串是否为数字

94

我需要在Dart中判断一个字符串是否为数字。它需要返回任何有效的数字类型在Dart中都为true。到目前为止,我的解决方案是:

bool isNumeric(String str) {
  try{
    var value = double.parse(str);
  } on FormatException {
    return false;
  } finally {
    return true;
  }
}

有本地的方法来做这件事吗?如果没有,有更好的方法来做吗?

10个回答

128

这可以简化一些。

void main(args) {
  print(isNumeric(null));
  print(isNumeric(''));
  print(isNumeric('x'));
  print(isNumeric('123x'));
  print(isNumeric('123'));
  print(isNumeric('+123'));
  print(isNumeric('123.456'));
  print(isNumeric('1,234.567'));
  print(isNumeric('1.234,567'));
  print(isNumeric('-123'));
  print(isNumeric('INFINITY'));
  print(isNumeric(double.INFINITY.toString())); // 'Infinity'
  print(isNumeric(double.NAN.toString()));
  print(isNumeric('0x123'));
}

bool isNumeric(String s) {
  if(s == null) {
    return false;
  }
  return double.parse(s, (e) => null) != null;
}
false   // null  
false   // ''  
false   // 'x'  
false   // '123x'  
true    // '123'  
true    // '+123'
true    // '123.456'  
false   // '1,234.567'  
false   // '1.234,567' (would be a valid number in Austria/Germany/...)
true    // '-123'  
false   // 'INFINITY'  
true    // double.INFINITY.toString()
true    // double.NAN.toString()
false   // '0x123'

来自 double.parse DartDoc

   * Examples of accepted strings:
   *
   *     "3.14"
   *     "  3.14 \xA0"
   *     "0."
   *     ".0"
   *     "-1.e3"
   *     "1234E+7"
   *     "+.12e-9"
   *     "-NaN"

此版本还接受十六进制数字

bool isNumeric(String s) {
  if(s == null) {
    return false;
  }

  // TODO according to DartDoc num.parse() includes both (double.parse and int.parse)
  return double.parse(s, (e) => null) != null || 
      int.parse(s, onError: (e) => null) != null;
}

print(int.parse('0xab'));

更新

由于{onError(String source)}现在已被弃用,您可以直接使用tryParse

bool isNumeric(String s) {
 if (s == null) {
   return false;
 }
 return double.tryParse(s) != null;
}

2
由于问题没有定义什么是数字,这绝对是一个解决方案,但请注意它也会接受“无穷大”和“NaN”。初始的“-”是否应该被允许也取决于确切的定义。如果还必须接受“0x123”,则可以使用num.parse而不是double.parse - lrn
谢谢你的提示!我考虑过询问什么应该被视为数字。当然,你是对的。有趣的是,“INFINITY”不被视为数字,但“NaN”却是。 - Günter Zöchbauer
1
它只接受double.INFINITY.toString()的确切输出,即"Infinity"(首字母大写,但不是大写)。 - lrn
谢谢!这绝对是比我的更好的解决方案。 - scrblnrd3
1
一行代码:bool isNumeric(String s) => s != null && double.tryParse(s) != null; - Taufik Nur Rahmanda
1
我发现isNumeric函数非常方便,所以我稍微修改了一下并将其放在了String扩展中:bool isDouble() { return double.tryParse(this) != null; } - Carl Smith

63

在Dart 2中,此方法已被弃用。

int.parse(s, onError: (e) => null)

取而代之,请使用

 bool _isNumeric(String str) {
    if(str == null) {
      return false;
    }
    return double.tryParse(str) != null;
  }

24

更简短。虽然它也能与double一起使用,但使用num更准确。

isNumeric(string) => num.tryParse(string) != null;

num.tryParse 的内部实现:

static num tryParse(String input) {
  String source = input.trim();
  return int.tryParse(source) ?? double.tryParse(source);
}

23

对于想要使用正则表达式的非本地方法的任何人

/// check if the string contains only numbers
 bool isNumeric(String str) {
        RegExp _numeric = RegExp(r'^-?[0-9]+$');
return _numeric.hasMatch(str);
}

这是最容易应用的方法。我建议将_numeric放在函数内部,因为这样它应该是即插即用的。结果应该是:bool isNumeric(String str) {RegExp _numeric = RegExp(r'^-?[0-9]+$');return _numeric.hasMatch(str); } - Thiago Silva
市面上最灵活和通用的解决方案! - Khushal

14
if (int.tryParse(value) == null) {
  return 'Only Number are allowed';
}

5

extension Numeric on String {
  bool get isNumeric => num.tryParse(this) != null ? true : false;
}

main() {
  print("1".isNumeric); // true
  print("-1".isNumeric); // true
  print("2.5".isNumeric); // true
  print("-2.5".isNumeric); // true
  print("0x14f".isNumeric); // true
  print("2,5".isNumeric); // false
  print("2a".isNumeric); // false
}

3
bool isOnlyNumber(String str) {
  try{
    var value = int.parse(str);
    return true;
  } on FormatException {
    return false;
  } 
}

1
能够简要解释一下这个程序是如何工作的/如何解决问题,以及它与现有答案的不同之处会很好。 - starball

0

在Matso Abgaryan和Günter Zöchbauer的回答基础上,

在使用flutter开发移动应用时,我可以在数字软键盘上输入','(逗号),并且double.tryParse()可能会返回Nan以及null - 因此,如果用户可以在软数字键盘上输入逗号,则仅检查null是不够的。如果字符串为空,则使用double.tryParse()将产生null - 因此,使用此函数将捕获该边缘情况;

bool _isNumeric(String str) {
   if (str == null) {
     return false;
   }
   return double.tryParse(str) is double; 
}

tryParse()的文档


0
import 'dart:convert';

void main() {
  //------------------------allMatches Example---------------------------------
  print('Example 1');

  //We want to extract ages from the following string:
  String str1 = 'Sara is 26 years old. Maria is 18 while Masood is 8.';

  //Declaring a RegExp object with a pattern that matches sequences of digits
  RegExp reg1 = new RegExp(r'(\d+)');

  //Iterating over the matches returned from allMatches
  Iterable allMatches = reg1.allMatches(str1);
  var matchCount = 0;
  allMatches.forEach((match) {
    matchCount += 1;
    print('Match ${matchCount}: ' + str1.substring(match.start, match.end));
  });

  //------------------------firstMatch Example---------------------------------
  print('\nExample 2');

  //We want to find the first sequence of word characters in the following string:
  //Note: A word character is any single letter, number or underscore
  String str2 = '#%^!_as22 d3*fg%';

  //Declaring a RegExp object with a pattern that matches sequences of word
  //characters
  RegExp reg2 = new RegExp(r'(\w+)');

  //Using the firstMatch function to display the first match found
  Match firstMatch = reg2.firstMatch(str2) as Match;
  print('First match: ${str2.substring(firstMatch.start, firstMatch.end)}');

  //--------------------------hasMatch Example---------------------------------
  print('\nExample 3');

  //We want to check whether a following strings have white space or not
  String str3 = 'Achoo!';
  String str4 = 'Bless you.';

  //Declaring a RegExp object with a pattern that matches whitespaces
  RegExp reg3 = new RegExp(r'(\s)');

  //Using the hasMatch method to check strings for whitespaces
  print(
      'The string "' + str3 + '" contains whitespaces: ${reg3.hasMatch(str3)}');
  print(
      'The string "' + str4 + '" contains whitespaces: ${reg3.hasMatch(str4)}');

  //--------------------------stringMatch Example-------------------------------
  print('\nExample 4');

  //We want to print the first non-digit sequence in the following strings;
  String str5 = '121413dog299toy01food';
  String str6 = '00Tom1231frog';

  //Declaring a RegExp object with a pattern that matches sequence of non-digit
  //characters
  RegExp reg4 = new RegExp(r'(\D+)');

  //Using the stringMatch method to find the first non-digit match:
  String? str5Match = reg4.stringMatch(str5);
  String? str6Match = reg4.stringMatch(str6);
  print('First match for "' + str5 + '": $str5Match');
  print('First match for "' + str6 + '": $str6Match');

  //--------------------------matchAsPrefix Example-----------------------------
  print('\nExample 5');

  //We want to check if the following strings start with the word "Hello" or not:
  String str7 = 'Greetings, fellow human!';
  String str8 = 'Hello! How are you today?';

  //Declaring a RegExp object with a pattern that matches the word "Hello"
  RegExp reg5 = new RegExp(r'Hello');

  //Using the matchAsPrefix method to match "Hello" to the start of the strings
  Match? str7Match = reg5.matchAsPrefix(str7);
  Match? str8Match = reg5.matchAsPrefix(str8);
  print('"' + str7 + '" starts with hello: ${str7Match != null}');
  print('"' + str8 + '" starts with hello: ${str8Match != null}');
}

在上面的例子中,您可以更好地了解RegExp,并且可以找到与您的字符串匹配的内容。 - nivedha

-1
bool isNumeric(String s) {
  double? numeric = double.tryParse(s);

  if (numeric == null) {
    return false;
  } else {
    return true;
  }
}

1
感谢您对贡献 Stack Overflow 社区的兴趣。这个问题已经有相当多的回答,其中一条回答已经得到社区的广泛验证。您确定您的方法之前没有被提出过吗?如果是这样,解释一下您的方法与众不同,在什么情况下可能更好,并且为什么您认为之前的答案不够满意会很有帮助。请编辑您的答案并提供解释,谢谢。 - Jeremy Caney

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接