2009-07-22 38 views
8

Tôi đang tìm một phương thức trả về boolean nếu chuỗi nó được chuyển là một số hợp lệ (ví dụ: "123.55e-9", "-333,556 "). Tôi không muốn chỉ làm:Thư viện Java để kiểm tra xem Chuỗi có chứa số * không * ngoại lệ

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

Rõ ràng, chức năng nên sử dụng một máy nhà nước (DFA) để phân tích chuỗi để đảm bảo ví dụ không hợp lệ sẽ không đánh lừa nó (ví dụ: "-21, 22.22.2 "," 33-2 "). Bạn có biết có thư viện nào tồn tại không? Tôi không thực sự muốn tự viết nó vì nó là một vấn đề rõ ràng như vậy mà tôi chắc chắn tôi sẽ tái phát minh ra bánh xe.

Cảm ơn,

Nick

+0

Tại sao chính xác không bạn muốn thế nào để sử dụng phân tích cú pháp từ BigDecimal? Đó là cách dễ nhất, thực sự. – Jorn

+0

Tôi muốn biết lý do tại sao bạn không muốn sử dụng đoạn trích bạn đã cung cấp? Nếu bạn cần phải _use_ số bạn phải phân tích nó? Nó chỉ là để xác nhận rằng một chuỗi có thể đi đến backend như-là? –

+0

Vì Ngoại lệ không phải là vấn đề cho trường hợp này. Ngoại trừ, ngoại trừ trường hợp không kiểm soát chương trình. – Malax

Trả lời

6

tôi sẽ tránh tái phát minh phương pháp này và đi với Apache Commons. Nếu bạn đang sử dụng Spring, Struts hoặc nhiều thư viện java thường được sử dụng khác, chúng thường có cả commons Apache. Bạn sẽ muốn tệp commons-lang.jar. Đây là phương pháp trong NumberUtils bạn muốn:

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 
3

sử dụng một regexp

+0

chính xác. và ở đây http://java.sun.com/j2se/1.5.0/docs/api/java/math/BigDecimal.html#BigDecimal(java.lang.String) bạn có một số thức ăn cho các bài kiểm tra đơn vị của bạn. – flybywire

+0

+1 vì Commons-Lang không cung cấp số này – skaffman

+0

Cảm ơn bạn đã chỉ cho tôi tại commons-lang. những thứ gọn gàng! – Malax

2

Vâng một biểu hiện thường xuyên nên làm các trick. Tôi chỉ biết. Net regexp nhưng tất cả các ngôn ngữ regex là khá giống nhau nên điều này sẽ giúp bạn bắt đầu. Tôi đã không thử nghiệm nó vì vậy bạn có thể muốn đá nó xung quanh một chút với lớp regex Java.

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

Một số cú pháp kiểm soát Regex:
? - Yếu tố tùy chọn
| - HOẶC nhà điều hành. Về cơ bản, tôi cho phép các số có hoặc không có dấu phẩy nếu chúng được định dạng chính xác.
[] - Tập hợp các ký tự cho phép
{,} - tối đa tối thiểu của nguyên tố
* - Bất kỳ số yếu tố, từ 0 đến vô cực
+ - Ít nhất một phần tử, 1 đến vô cùng
\ - Escape nhân vật
. - Bất kỳ ký tự (Do đó tại sao nó được thoát)

+0

+1 để triển khai thực tế – dfa

+0

thực tế biểu thức này sẽ khớp với 22,22,2.14123415e1 – Salandur

+0

Và nó sẽ không khớp với 1e-1. – Bombe

2

Đây là một regexp dựa chức năng tiện ích làm việc tốt (không thể phù hợp với những "" kiểm tra trong regexp trong khi vẫn giữ nó có thể đọc được):

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

} 
2

Các biểu hiện thường xuyên chính xác được quy định trong Javadocs cho Double.valueOf(String).

Để tránh gọi phương pháp này trên một chuỗi không hợp lệ và có một NumberFormatException được ném ra, biểu thức chính quy dưới đây có thể được sử dụng để sàng lọc các chuỗi đầu vào:

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 
} 
Các vấn đề liên quan