Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reg~x for the N~number

Tags:

java

string

Would be grateful your help.

What would be elegant Regx to check a String whether it holds a number ? any suggestions? thanks.

like image 516
Njax3SmmM2x2a0Zf7Hpd Avatar asked Dec 09 '22 13:12

Njax3SmmM2x2a0Zf7Hpd


2 Answers

I don't think that an exception (even if it is triggered) is that much more expensive than a regular expression - you'd have to profile it and see if it really makes a difference.

That said, a regular expression that implements the BigDecimal grammar according to the Java Docs is

[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?

Explanation:

[+-]?       # optional sign
(?:         # required significand: either...
 \d+        # a number
 (?:\.\d*)? # optionally followed by a dot, optionally followed by more digits
 |          # or...
 \.\d+      # just a dot, followed by digits (in this case required)
)           # end of significand
(?:         # optional exponent
 [eE]       # required exponent indicator
 [+-]?      # optional sign
 \d+        # required digits
)?          # end of exponent

If you want to allow different number formats (and thousands separators) you could first get those values from DecimalFormatSymbols and build your regex with it.

Something like this (I don't know Java, so feel free to correct my Syntax Errors):

// you need java.util.regex.Pattern and java.text.DecimalFormatSymbols
string ds = Pattern.quote(DecimalFormatSymbols.getDecimalSeparator())
string gs = Pattern.quote(DecimalFormatSymbols.getGroupingSeparator())
string ms = Pattern.quote(DecimalFormatSymbols.getMinusSign())
string es = Pattern.quote(DecimalFormatSymbols.getExponentSeparator())

string myre = 
    "(?xi)\n       # verbose, case-insensitive regex" +
    "[+" +ms+ "]?  # optional sign\n" +
    "(?:           # required significand: either...\n" +
    " (?:\\d{1,3}(?:" +gs+ "\\d{3}|\\d++) # a number with optional thousand separators,\n" +
    " (?:" +ds+ "\\d*)? # optionally followed by a dot, optionally followed by more digits\n" +
    " |            # or...\n" +
      ds+ "\\d+    # just a dot, followed by digits (in this case required)\n" +
    ")             # end of significand\n" +
    "(?:           # optional exponent\n" +
      es+ "        # required exponent indicator\n" +
    " [+" +ms+ "]? # optional sign\n" +
    " \\d+         # required digits\n" +
    ")?            # end of exponent"

boolean foundMatch = subjectString.matches(myregex);

You could then replace the locale-dependent bits back into their US counterparts before handing the number over for BigDecimal conversion, if that's not locale-aware.

like image 187
Tim Pietzcker Avatar answered Dec 13 '22 23:12

Tim Pietzcker


Take a look at the implementation of the Apache's NumberUtils.isNumber. I wouldn't recommend using regular expressions for such validation.

like image 29
Alex Nikolaenkov Avatar answered Dec 13 '22 23:12

Alex Nikolaenkov