简体   繁体   English

Java:检查命令行参数

[英]Java: checking command line arguments

I know that easily I can use a try/catch to check command line arguments are a double. 我知道我可以轻松地使用try / catch来检查命令行参数是否为double。

I'm seeking a way to check this without using a costly try/catch block. 我正在寻找一种无需使用昂贵的try / catch块即可进行检查的方法。 I'm fairly new to Java. 我是Java的新手。 I'ved searched a few forums but haven't found anything specific to my issue. 我搜索了一些论坛,但未发现与我的问题有关的任何内容。

System.out.println(Double.parseDouble(args[1]));

^^This will cause an error. ^^这将导致错误。 besides putting this in a try/catch can someone point me towards data validation that will prevent this? 除了将其放在try / catch中之外,是否有人可以将我指向可以防止这种情况的数据验证? assume args[1] is a string of text. 假设args [1]是文本字符串。

The try - catch approach is the generally accepted way to do this, primarily because there are actually a lot of formats a valid double can have: try - catch方法是普遍接受的方法,主要是因为有效的double实际上可以具有很多格式:

double a = 42.e10;  // or 42.E10
double b = 42.f;    // or 42.F
double c = 42.d;    // or 42.D
double d = 010E010D;
double e = 0x1.fffffffffffffP+1023;
double f = 0x1.0p-1022;

All of these are valid doubles and can be parsed from a string via parseDouble() . 所有这些都是有效的双精度,可以通过parseDouble()从字符串中进行解析。 Double.parseDouble("NaN") and Double.parseDouble("Infinity") are also valid (although NaN and Infinity aren't literals). Double.parseDouble("NaN")Double.parseDouble("Infinity")也是有效的(尽管NaNInfinity不是文字)。 Not to mention parseDouble() also deals with leading or trailing whitespaces. 更不用说parseDouble()也处理前导或尾随空格。 So my answer is: don't ! 所以我的答案是: 不要 Use the try - catch approach. 使用try - catch方法。 It is possible to construct a regex that matches some subset of (or maybe even all) valid double formats, but I doubt that will actually be more efficient than catching and handling a NumberFormatException . 可以构建匹配的(或者甚至全部)有效的双格式的一些子集的正则表达式,但我怀疑这实际上是比捕捉和处理更高效的NumberFormatException


A full regex is actually explained in the documentation of valueOf() : 完整的正则表达式实际上在valueOf()的文档中进行了说明:

To avoid calling this method on an invalid string and having a NumberFormatException be thrown, the regular expression below can be used to screen the input string: 为避免在无效字符串上调用此方法并引发NumberFormatException异常,可以使用以下正则表达式来筛选输入字符串:

  final String Digits = "(\\\\p{Digit}+)"; final String HexDigits = "(\\\\p{XDigit}+)"; // an exponent is 'e' or 'E' followed by an optionally // signed decimal integer. final String Exp = "[eE][+-]?"+Digits; final String fpRegex = ("[\\\\x00-\\\\x20]*"+ // Optional leading "whitespace" "[+-]?(" + // Optional sign character "NaN|" + // "NaN" string "Infinity|" + // "Infinity" string // A decimal floating-point string representing a finite positive // number without a leading sign has at most five basic pieces: // Digits . Digits ExponentPart FloatTypeSuffix // // Since this method allows integer-only strings as input // in addition to strings of floating-point literals, the // two sub-patterns below are simplifications of the grammar // productions from section 3.10.2 of // The Java™ Language Specification. // Digits ._opt Digits_opt ExponentPart_opt FloatTypeSuffix_opt "((("+Digits+"(\\\\.)?("+Digits+"?)("+Exp+")?)|"+ // . Digits ExponentPart_opt FloatTypeSuffix_opt "(\\\\.("+Digits+")("+Exp+")?)|"+ // Hexadecimal strings "((" + // 0[xX] HexDigits ._opt BinaryExponent FloatTypeSuffix_opt "(0[xX]" + HexDigits + "(\\\\.)?)|" + // 0[xX] HexDigits_opt . HexDigits BinaryExponent FloatTypeSuffix_opt "(0[xX]" + HexDigits + "?(\\\\.)" + HexDigits + ")" + ")[pP][+-]?" + Digits + "))" + "[fFdD]?))" + "[\\\\x00-\\\\x20]*");// Optional trailing "whitespace" if (Pattern.matches(fpRegex, myString)) Double.valueOf(myString); // Will not throw NumberFormatException else { // Perform suitable alternative action } 

As you can see it's somewhat of a nasty regex. 如您所见,它有点讨厌。

As commenter Óscar López says, just use a try/catch block and catch NumberFormatException. 正如评论员ÓscarLópez所说,只需使用try / catch块并捕获NumberFormatException。 This is the right way to ensure that the target string is a properly formatted double and the potential overhead of the try/catch construct is worth the correctness and clarity of the program. 这是确保目标字符串为正确格式的double的正确方法,并且try / catch构造的潜在开销值得程序的正确性和清晰度。

Double d = null;
try {
  d = Double.parseDouble(args[1]);
} catch (NumberFormatException nfe) {
  // TODO
}

Java has no method like isDouble or isNumeric out of the box, But you could write them on your own: Java没有开箱即用的isDoubleisNumeric这样的方法,但是您可以自己编写它们:

public static boolean isDouble(String s) {
    try {
        Double.parseDouble(s);
    } catch (NumberFormatException e) {
        return false;
    }
    return true;
}

But double has many ways to be writen it: 但是double有很多写方法:

  • 23.2 23.2
  • 23f 23楼
  • 23e10 23e10
  • 2_3.4_5 (cannot be parsed with Double#parseDouble(String) ) 2_3.4_5(无法使用Double#parseDouble(String)解析)
  • 2_3E1_0d (cannot be parsed with Double#parseDouble(String) ) 2_3E1_0d(无法使用Double#parseDouble(String)解析)

If you just want to check for the XX.XXX pattern this is the way to go using RegEx: 如果只想检查XX.XXX模式,这是使用RegEx的方法:

public static boolean isDoubleDigits(String s) {
    return s.matches("\\d+(\\.\\d{1,2})?");
}

Why not use a framework for command-line input validation? 为什么不使用框架进行命令行输入验证? Checkout Apache Commons CLI project 签出Apache Commons CLI项目

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM