Regex to find a float

Try this:

String re1="^([+-]?\\d*\\.?\\d*)$";

The right way for this problem isn't to use a regex, but just to use:

try {
     Float.parseFloat(string)
     return true;
}
catch (NumberFormatException ex) {
     return false;
}

Works perfectly fine, is the same code that is later used to parse the float and therefore bug free (or if it isn't we have a much bigger problem at hand).


After balking at the accepted answer (and the other two relevant ones), I decided to provide a new one. Then I found Christoffer Hammarström's Sep 1 '16 at 8:40 mostly hidden comment on Paulpro's answer (which was accepted).

Here's the accepted answer:

String re1="^([+-]?\d*\.?\d*)$";

Here's Christoffer's comment:

This matches the empty string, or a single dot, or a plus or a minus by itself.

In fact, none of the 3 answers that adhere to the requirement of the OP do a good job, which is that he must provide an RE to some other class object and allow an end user to type in any valid floating point number.

Here is my case for a new answer.

In summary, my answer is [+-]?(\d+|\d+\.\d+|\.\d+|\d+\.)([eE]\d+)?. You must add ^ at the beginning and $ at the end the expression if the class object might otherwise give a pass to invalid leading or trailing characters.

Here's how I read the expression as written above:

[+-]?

This means a leading sign character is allowed but not required.

( \d+ | \d+\.\d+ | \.\d+ | \d+\. )

I've added whitespace to make it easier to see what's going on. This means accept the 4 forms of commonly accepted expressions of signless non-scientific-notation floating point numbers. Many computer languages allow for all four. Perhaps with more grouping, this part of the expression could be compressed but at the expense of readability.

([eE]\d+)?

This final part means a scientific notation suffix is allowed by not required.

Here's all the code.

$ cat Tester.java | sed 's/^/    /'

import java.util.*;
import java.util.regex.*;

public class Tester {

    private class TestVal {
        private String  val;
        private boolean accepted;
        private boolean expect;
        private boolean tested;
        public TestVal (String testValue, boolean expectedResult) {
            val = testValue;
            expect = expectedResult;
            reset();
        }
        public String   getValue    () { return val; }
        public boolean  getExpect   () { return expect; }
        public void     reset       () { tested = false; accepted = false; }
        public boolean  getAccepted () { return accepted; }
        public boolean  getTested   () { return tested; }
        public void     setAccepted (boolean newAccept) { tested = true; accepted = newAccept; }
    }

    private ArrayList<TestVal> tests = new ArrayList<TestVal>();

    public void doRETest (Pattern re, TestVal tv) {
            boolean matches = re.matcher(tv.getValue()).matches();
            boolean ok = matches == tv.getExpect();
            String result = ok ? "success" : "fail";
            System.out.println(String.format("%10s matches=%5s: %s", tv.getValue(), matches, result));
            tv.setAccepted(ok);
    }

    private void testsSummary () {
        int skipped = 0;
        int passes = 0;
        int failures = 0;
        for (TestVal tv : tests)
            if (tv.getTested())
                if (tv.getAccepted())
                    passes++;
                else
                    failures++;
            else
                skipped++;
        System.out.println(String.format("\npassed %d tests, failed %d tests, and %d tests skipped\n\n", passes, failures, skipped));
    }

    public void doRETests (String re) {
        Pattern p = Pattern.compile(re);
        System.out.println(String.format("testing %s", re));
        for (TestVal tv : tests) {
            tv.reset();
            doRETest(p, tv);
        }
        testsSummary();
    }

    public Tester () {
        tests.add(new TestVal("1", true));
        tests.add(new TestVal(".1", true));
        tests.add(new TestVal("1.", true));
        tests.add(new TestVal("1.0", true));

        tests.add(new TestVal("+1", true));
        tests.add(new TestVal("+.1", true));
        tests.add(new TestVal("+1.", true));
        tests.add(new TestVal("+1.0", true));

        tests.add(new TestVal("-1", true));
        tests.add(new TestVal("-.1", true));
        tests.add(new TestVal("-1.", true));
        tests.add(new TestVal("-1.0", true));

        tests.add(new TestVal("1e2", true));
        tests.add(new TestVal(".1e2", true));
        tests.add(new TestVal("1.e2", true));
        tests.add(new TestVal("1.0e2", true));

        tests.add(new TestVal("1.0e2.3", false));
        tests.add(new TestVal(".", false));
        tests.add(new TestVal("", false));
        tests.add(new TestVal("+", false));
        tests.add(new TestVal("-", false));
        tests.add(new TestVal("a", false));
    }

    public static void main (String args[]) {
        Tester t = new Tester();

        String paulpro  = "^([+-]?\\d*\\.?\\d*)$";
        String lucac    = "^([+-]?(\\d+\\.)?\\d+)$";
        String armaj    = "\\d+\\.\\d+";
        String j6t7     = "[+-]?(\\d+|\\d+\\.\\d+|\\.\\d+|\\d+\\.)([eE]\\d+)?";

        t.doRETests(paulpro);
        t.doRETests(lucac);
        t.doRETests(armaj);
        t.doRETests(j6t7);

    }

}

And here's what happened when I executed it.

$ javac Tester.java && java Tester | sed 's/^/    /'

testing ^([+-]?\d*\.?\d*)$
         1 matches= true: success
        .1 matches= true: success
        1. matches= true: success
       1.0 matches= true: success
        +1 matches= true: success
       +.1 matches= true: success
       +1. matches= true: success
      +1.0 matches= true: success
        -1 matches= true: success
       -.1 matches= true: success
       -1. matches= true: success
      -1.0 matches= true: success
       1e2 matches=false: fail
      .1e2 matches=false: fail
      1.e2 matches=false: fail
     1.0e2 matches=false: fail
   1.0e2.3 matches=false: success
         . matches= true: fail
           matches= true: fail
         + matches= true: fail
         - matches= true: fail
         a matches=false: success

passed 14 tests, failed 8 tests, and 0 tests skipped


testing ^([+-]?(\d+\.)?\d+)$
         1 matches= true: success
        .1 matches=false: fail
        1. matches=false: fail
       1.0 matches= true: success
        +1 matches= true: success
       +.1 matches=false: fail
       +1. matches=false: fail
      +1.0 matches= true: success
        -1 matches= true: success
       -.1 matches=false: fail
       -1. matches=false: fail
      -1.0 matches= true: success
       1e2 matches=false: fail
      .1e2 matches=false: fail
      1.e2 matches=false: fail
     1.0e2 matches=false: fail
   1.0e2.3 matches=false: success
         . matches=false: success
           matches=false: success
         + matches=false: success
         - matches=false: success
         a matches=false: success

passed 12 tests, failed 10 tests, and 0 tests skipped


testing \d+\.\d+
         1 matches=false: fail
        .1 matches=false: fail
        1. matches=false: fail
       1.0 matches= true: success
        +1 matches=false: fail
       +.1 matches=false: fail
       +1. matches=false: fail
      +1.0 matches=false: fail
        -1 matches=false: fail
       -.1 matches=false: fail
       -1. matches=false: fail
      -1.0 matches=false: fail
       1e2 matches=false: fail
      .1e2 matches=false: fail
      1.e2 matches=false: fail
     1.0e2 matches=false: fail
   1.0e2.3 matches=false: success
         . matches=false: success
           matches=false: success
         + matches=false: success
         - matches=false: success
         a matches=false: success

passed 7 tests, failed 15 tests, and 0 tests skipped


testing [+-]?(\d+|\d+\.\d+|\.\d+|\d+\.)([eE]\d+)?
         1 matches= true: success
        .1 matches= true: success
        1. matches= true: success
       1.0 matches= true: success
        +1 matches= true: success
       +.1 matches= true: success
       +1. matches= true: success
      +1.0 matches= true: success
        -1 matches= true: success
       -.1 matches= true: success
       -1. matches= true: success
      -1.0 matches= true: success
       1e2 matches= true: success
      .1e2 matches= true: success
      1.e2 matches= true: success
     1.0e2 matches= true: success
   1.0e2.3 matches=false: success
         . matches=false: success
           matches=false: success
         + matches=false: success
         - matches=false: success
         a matches=false: success

passed 22 tests, failed 0 tests, and 0 tests skipped

Tags:

Java

Regex