在解析字符串之前,如何检查它是否是一个数字?
当前回答
试试这个:
public boolean isNumber(String str)
{
short count = 0;
char chc[] = {'0','1','2','3','4','5','6','7','8','9','.','-','+'};
for (char c : str.toCharArray())
{
for (int i = 0;i < chc.length;i++)
{
if( c == chc[i]){
count++;
}
}
}
if (count != str.length() )
return false;
else
return true;
}
其他回答
要匹配仅包含ASCII数字的以10为基数的正整数,请使用:
public static boolean isNumeric(String maybeNumeric) {
return maybeNumeric != null && maybeNumeric.matches("[0-9]+");
}
为什么每个人都在推动异常/正则表达式解决方案?
虽然我能理解大多数人都喜欢使用try/catch,但如果你想频繁地使用它……这可能会非常累人。
我在这里所做的是使用regex、parsennumber()方法和数组搜索方法来查看哪个是最有效的。这一次,我只研究了整数。
public static boolean isNumericRegex(String str) {
if (str == null)
return false;
return str.matches("-?\\d+");
}
public static boolean isNumericArray(String str) {
if (str == null)
return false;
char[] data = str.toCharArray();
if (data.length <= 0)
return false;
int index = 0;
if (data[0] == '-' && data.length > 1)
index = 1;
for (; index < data.length; index++) {
if (data[index] < '0' || data[index] > '9') // Character.isDigit() can go here too.
return false;
}
return true;
}
public static boolean isNumericException(String str) {
if (str == null)
return false;
try {
/* int i = */ Integer.parseInt(str);
} catch (NumberFormatException nfe) {
return false;
}
return true;
}
我得到的速度结果是:
Done with: for (int i = 0; i < 10000000; i++)...
With only valid numbers ("59815833" and "-59815833"):
Array numeric took 395.808192 ms [39.5808192 ns each]
Regex took 2609.262595 ms [260.9262595 ns each]
Exception numeric took 428.050207 ms [42.8050207 ns each]
// Negative sign
Array numeric took 355.788273 ms [35.5788273 ns each]
Regex took 2746.278466 ms [274.6278466 ns each]
Exception numeric took 518.989902 ms [51.8989902 ns each]
// Single value ("1")
Array numeric took 317.861267 ms [31.7861267 ns each]
Regex took 2505.313201 ms [250.5313201 ns each]
Exception numeric took 239.956955 ms [23.9956955 ns each]
// With Character.isDigit()
Array numeric took 400.734616 ms [40.0734616 ns each]
Regex took 2663.052417 ms [266.3052417 ns each]
Exception numeric took 401.235906 ms [40.1235906 ns each]
With invalid characters ("5981a5833" and "a"):
Array numeric took 343.205793 ms [34.3205793 ns each]
Regex took 2608.739933 ms [260.8739933 ns each]
Exception numeric took 7317.201775 ms [731.7201775 ns each]
// With a single character ("a")
Array numeric took 291.695519 ms [29.1695519 ns each]
Regex took 2287.25378 ms [228.725378 ns each]
Exception numeric took 7095.969481 ms [709.5969481 ns each]
With null:
Array numeric took 214.663834 ms [21.4663834 ns each]
Regex took 201.395992 ms [20.1395992 ns each]
Exception numeric took 233.049327 ms [23.3049327 ns each]
Exception numeric took 6603.669427 ms [660.3669427 ns each] if there is no if/null check
免责声明:我并没有声称这些方法是100%优化的,它们只是为了演示数据
当且仅当数字为4个字符或更少,并且每个字符串总是一个数字时,例外获胜……既然如此,为什么还要支票呢?
简而言之,如果使用try/catch频繁地遇到无效数字,那将非常痛苦,这是有意义的。我一直遵循的一个重要规则是永远不要在程序流中使用try/catch。这是一个例子。
有趣的是,简单的if char <0 || >9写起来非常简单,容易记忆(应该可以在多种语言中工作),并且赢得了几乎所有的测试场景。
唯一的缺点是,我猜Integer.parseInt()可能处理非ASCII数字,而数组搜索方法不。
对于那些想知道为什么我说很容易记住字符数组1的人来说,如果你知道没有负号,你可以很容易地得到一些像这样的浓缩:
public static boolean isNumericArray(String str) {
if (str == null)
return false;
for (char c : str.toCharArray())
if (c < '0' || c > '9')
return false;
return true;
最后,作为最后的说明,我很好奇在所有投票都被接受的例子中的赋值操作符。加上赋值
double d = Double.parseDouble(...)
不仅没有用,因为您甚至没有使用该值,而且它浪费了处理时间,并使运行时增加了几纳秒(这导致测试中增加了100-200毫秒)。我不明白为什么有人会这么做,因为这实际上是降低性能的额外工作。
你可能会认为这会被优化掉……虽然也许我应该检查字节码,看看编译器在做什么。这并不能解释为什么它对我来说总是更长,尽管它以某种方式被优化了……所以我想知道发生了什么。注意:这里所说的更长,我的意思是运行测试10000000次迭代,并且运行该程序多次(10x+)总是显示它更慢。
编辑:更新了Character.isDigit()的测试
我修改了CraigTP的解决方案,使其接受科学计数法,同时接受点和逗号作为小数分隔符
^-?\d+([,\.]\d+)?([eE]-?\d+)?$
例子
var re = new RegExp("^-?\d+([,\.]\d+)?([eE]-?\d+)?$");
re.test("-6546"); // true
re.test("-6546355e-4456"); // true
re.test("-6546.355e-4456"); // true, though debatable
re.test("-6546.35.5e-4456"); // false
re.test("-6546.35.5e-4456.6"); // false
这是我知道的最快的方法来检查字符串是否为数字:
public static boolean isNumber(String str){
int i=0, len=str.length();
boolean a=false,b=false,c=false, d=false;
if(i<len && (str.charAt(i)=='+' || str.charAt(i)=='-')) i++;
while( i<len && isDigit(str.charAt(i)) ){ i++; a=true; }
if(i<len && (str.charAt(i)=='.')) i++;
while( i<len && isDigit(str.charAt(i)) ){ i++; b=true; }
if(i<len && (str.charAt(i)=='e' || str.charAt(i)=='E') && (a || b)){ i++; c=true; }
if(i<len && (str.charAt(i)=='+' || str.charAt(i)=='-') && c) i++;
while( i<len && isDigit(str.charAt(i)) ){ i++; d=true;}
return i==len && (a||b) && (!c || (c && d));
}
static boolean isDigit(char c){
return c>='0' && c<='9';
}
如果你们用下面的方法来检查:
public static boolean isNumeric(String str) {
NumberFormat formatter = NumberFormat.getInstance();
ParsePosition pos = new ParsePosition(0);
formatter.parse(str, pos);
return str.length() == pos.getIndex();
}
然后输入非常长的字符串会发生什么,比如我调用这个方法:
System.out.println(isNumeric("94328948243242352525243242524243425452342343948923"));
结果是“真”,也是一个太大的数字! 如果你使用regex来检查,同样的事情也会发生! 所以我宁愿使用“解析”方法来检查,就像这样:
public static boolean isNumeric(String str) {
try {
int number = Integer.parseInt(str);
return true;
} catch (Exception e) {
return false;
}
}
结果就如我所料!
推荐文章
- 我应该如何从字符串中删除所有的前导空格?- - - - - -斯威夫特
- 如何格式化Joda-Time DateTime仅为mm/dd/yyyy?
- 如何在POM.xml中引用环境变量?
- 如何在android中复制一个文件?
- 将整数转换为字符串,以逗号表示千
- 将JavaScript字符串中的多个空格替换为单个空格
- 接口方法的最终参数-有什么意义?
- Java中的@UniqueConstraint注释
- printf()和puts()在C语言中的区别是什么?
- 如何在清洁模式下运行eclipse ?如果我们这样做会发生什么?
- 获取java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory异常
- Java中的正则表达式命名组
- c#和Java的主要区别是什么?
- 什么是NullPointerException,我如何修复它?
- 在Java中使用“final”修饰符