Java 库检查字符串是否包含数字*没有*异常

发布于 2024-07-28 23:38:08 字数 448 浏览 3 评论 0原文

我正在寻找一种方法,如果传递的字符串是有效数字(例如“123.55e-9”、“-333,556”),则返回布尔值。 我不想只想这样做:

public boolean isANumber(String s) {
    try { 
        BigDecimal a = new BigDecimal(s); 
        return true;
    } catch (NumberFormatException e) {
        return false;
    }
}

显然,该函数应该使用状态机(DFA)来解析字符串,以确保无效的示例不会欺骗它(例如“-21,22.22. 2”、“33-2”)。 你知道是否存在这样的图书馆吗? 我真的不想自己写它,因为这是一个如此明显的问题,我确信我会重新发明轮子。

谢谢,

尼克

I'm looking for a method that returns a boolean if the String it is passed is a valid number (e.g. "123.55e-9", "-333,556"). I don't want to just do:

public boolean isANumber(String s) {
    try { 
        BigDecimal a = new BigDecimal(s); 
        return true;
    } catch (NumberFormatException e) {
        return false;
    }
}

Clearly, the function should use a state machine (DFA) to parse the string to make sure invalid examples don't fool it (e.g. "-21,22.22.2", "33-2"). Do you know if any such library exists? I don't really want to write it myself as it's such an obvious problem that I'm sure I'd be re-inventing the wheel.

Thanks,

Nick

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

淡淡の花香 2024-08-04 23:38:08

我会避免重新发明这种方法并使用 Apache Commons。 如果您使用 Spring、Struts 或许多其他常用的 java 库,它们通常包含 Apache commons。 您将需要 commons-lang.jar 文件。 这是 NumberUtils 你会想要:

isNumber[1]

public static boolean isNumber(java.lang.String str)
Checks whether the String a valid Java number.

Valid numbers include hexadecimal marked with the 0x qualifier, scientific notation and numbers marked with a type qualifier (e.g. 123L).

Null and empty String will return false.

Parameters:
str - the String to check
Returns:
true if the string is a correctly formatted number

I would avoid re-inventing this method and go with Apache Commons. If your using Spring, Struts or many other commonly used java libraries, they often have Apache commons included. You will want the commons-lang.jar file. Here is the method in NumberUtils you would want:

isNumber[1]

public static boolean isNumber(java.lang.String str)
Checks whether the String a valid Java number.

Valid numbers include hexadecimal marked with the 0x qualifier, scientific notation and numbers marked with a type qualifier (e.g. 123L).

Null and empty String will return false.

Parameters:
str - the String to check
Returns:
true if the string is a correctly formatted number
潜移默化 2024-08-04 23:38:08

确切的正则表达式在 Javadocs 中为 Double.valueOf(String)

为了避免在无效字符串上调用此方法并引发 NumberFormatException,可以使用下面的正则表达式来筛选输入字符串:

最终字符串数字 = "(\\p{Digit}+)"; 
  最终字符串 HexDigits = "(\\p{XDigit}+)"; 
  // 指数是 'e' 或 'E' 后跟一个可选的  
  // 有符号十进制整数。 
  最终字符串 Exp = "[eE][+-]?"+数字; 
  最终字符串 fpRegex = 
         ("[\\x00-\\x20]*"+ // 可选的前导“空格” 
          "[+-]?(" + // 可选符号字符 
          “南|”   + //“NaN”字符串 
          “无限|”   + //“无穷大”字符串 

          // 表示有限正数的十进制浮点字符串 
          // 没有前导符号的数字最多有五个基本部分: 
          // 数字 .   数字 指数部分 FloatTypeSuffix 
          //  
          // 由于此方法允许仅整数字符串作为输入 
          // 除了浮点文字字符串之外, 
          // 下面的两个子模式是语法的简化 
          // Java 语言规范第二版的产生式  
          // 版本,第 3.10.2 节。 

          // 数字 ._opt Digits_opt ExponentPart_opt FloatTypeSuffix_opt 
          "((("+数字+"(\\.)?("+数字+"?)("+Exp+")?)|"+ 

          // .   数字 ExponentPart_opt FloatTypeSuffix_opt 
          "(\\.("+数字+")("+Exp+")?)|"+ 

          // 十六进制字符串 
          “((”+ 
          // 0[xX] HexDigits ._opt BinaryExponent FloatTypeSuffix_opt 
          "(0[xX]" + 十六进制数字 + "(\\.)?)|"   + 

          // 0[xX] HexDigits_opt 。   HexDigits BinaryExponent FloatTypeSuffix_opt 
          "(0[xX]" + 十六进制数字 + "?(\\.)" + 十六进制数字 + ")" + 

          “)[pP][+-]?”   + 数字 + "))" + 
          “[fFdD]?))”+ 
          "[\\x00-\\x20]*");   // 可选的尾随“空白” 
       
  if (Pattern.matches(fpRegex, myString)) 
      Double.valueOf(myString);   // 不会抛出 NumberFormatException 
  别的 { 
      // 执行合适的替代操作 
  } 
  

The exact regular expression is specified in the Javadocs for Double.valueOf(String).

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:

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 the Java Language Specification, 2nd 
        // edition, section 3.10.2.

        // 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
}
凉墨 2024-08-04 23:38:08

这是一个基于正则表达式的实用函数,运行良好(无法在正则表达式中安装“”检查,同时保持其可读性):

public class TestRegexp {
    static final String NUM_REGEX=
        "-?((([0-9]{1,3})(,[0-9]{3})*)|[0-9]*)(\\.[0-9]+)?([Ee][0-9]*)?";
    public static boolean isNum(String s) {
            return s!=null && s.length()>0 && s.matches(NUM_REGEX);  
    }
    public static void main(String[]args) {
        String[] values={
                "",
                "0",
                "0.1",
                ".1",
                "-.5E5",
                "-12,524.5E5",
                "-452,456,456,466.5E5",
                "-452,456,456,466E5",
                "22,22,2.14123415e1",
        };
        for (String value : values) {
            System.out.println(value+" is a number: "
            +isNum(value));
        }
    }

}

Here is a regexp based utility function working fine (couldn't fit the "" check in the regexp while keeping it readable):

public class TestRegexp {
    static final String NUM_REGEX=
        "-?((([0-9]{1,3})(,[0-9]{3})*)|[0-9]*)(\\.[0-9]+)?([Ee][0-9]*)?";
    public static boolean isNum(String s) {
            return s!=null && s.length()>0 && s.matches(NUM_REGEX);  
    }
    public static void main(String[]args) {
        String[] values={
                "",
                "0",
                "0.1",
                ".1",
                "-.5E5",
                "-12,524.5E5",
                "-452,456,456,466.5E5",
                "-452,456,456,466E5",
                "22,22,2.14123415e1",
        };
        for (String value : values) {
            System.out.println(value+" is a number: "
            +isNum(value));
        }
    }

}
柏拉图鍀咏恒 2024-08-04 23:38:08

是的,正则表达式应该可以解决问题。 我只知道 .Net 正则表达式,但所有正则表达式语言都非常相似,所以这应该可以帮助您入门。 我没有对其进行测试,因此您可能需要使用 Java 正则表达式类稍微尝试一下。

"-?(([0-9]{1,3}(,[0-9{3,3})*)|[0-9]*)(\.[0-9]+(e-?[0-9]*)?)?"

一些正则表达式控制语法:
? - 可选元素
| - 或运算符。 基本上,如果格式正确,我允许带或不带逗号的数字。
[ ] - 允许的字符集
{ , } - 元素的最小最大值
* - 任意数量的元素,0 到无穷大
+ - 至少一个元素,1 到无穷大
\ - 转义字符
。 - 任何字符(因此它被转义)

Yeah a regular expression should do the trick. I only know .Net regexp but all regex languages are fairly similar so this should get you started. I didn't test it so you might want to kick it around a bit with the Java regex class.

"-?(([0-9]{1,3}(,[0-9{3,3})*)|[0-9]*)(\.[0-9]+(e-?[0-9]*)?)?"

Some of the Regex control syntax:
? - Optional element
| - OR operator. Basically I allowed numbers with or without commas if they were formatted correctly.
[ ] - Set of allowed characters
{ , } - Minimum maximum of element
* - Any number of elements, 0 to infinity
+ - At least one element, 1 to infinity
\ - Escape character
. - Any character (Hence why it was escaped)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文