正则表达式查找浮点数

问题描述 投票:0回答:7

我以前从未使用过正则表达式,但这个java函数需要它(如下所示:如何设置Edittext视图仅允许两个数值和两个小数值,如##.##

我基本上只需要从文本框中获取一个浮动,应该很简单。我使用了一个工具,它说这应该有效:

String re1="([+-]?\\d*\\.\\d+)(?![-+0-9\\.])";

但它似乎不起作用,它不允许我在文本框中输入任何内容。

正确的做法是什么?谢谢

java regex
7个回答
11
投票

试试这个:

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

8
投票

解决这个问题的正确方法不是使用正则表达式,而只是使用:

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

工作得很好,与稍后用于解析浮点的代码相同,因此没有错误(或者如果不是,我们手头有一个更大的问题)。


5
投票

在对已接受的答案(以及其他两个相关答案)犹豫不决后,我决定提供一个新答案。然后我发现了 Christoffer Hammarström 于 2016 年 9 月 1 日 8:40 发表的对 Paulpro 答案的大部分隐藏评论(已被接受)。

这是已接受的答案:

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

这是克里斯托弗的评论:

这匹配空字符串、单个点、加号或减号 就其本身而言。

事实上,符合OP要求的3个答案都没有做得很好,即他必须向其他类对象提供RE并允许最终用户输入任何有效的浮点数。

这是我寻求新答案的案例。

总而言之,我的答案是

[+-]?(\d+|\d+\.\d+|\.\d+|\d+\.)([eE]\d+)?
。如果类对象可能会传递给无效的前导或尾随字符,则必须在表达式的开头添加
^
并在表达式末尾添加
$

这是我如何阅读上面写的表达式:

[+-]?

这意味着允许使用前导符号字符,但不是必需的。

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

我添加了空格,以便更容易看到发生了什么。这意味着接受无符号非科学计数法浮点数的 4 种普遍接受的表达式。许多计算机语言都允许这四种语言。也许通过更多的分组,这部分表达式可以被压缩,但会牺牲可读性。

([eE]\d+)?

最后一部分意味着科学计数法后缀是允许的,但不是必需的。

这是所有代码。

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

    }

}

这就是我执行它时发生的情况。

$ 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

4
投票

这才是正确的做法:

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

或者如果您还查看其他文本的中间:

String floatRegexp="([+-]?(\\d+\\.)?\\d+)";

如果您不寻找减号/加号:

String floatRegexp="^(\\d+\\.)?\\d+$";

0
投票

这个答案来自 Johan Sjöberg https://stackoverflow.com/a/12235002/4035655

您可以尝试使用正则表达式来匹配数字

\\d+\\.\\d+

这可能看起来像

Pattern p = Pattern.compile("\\d+\\.\\d+");
Matcher m = p.matcher("Sstring>26.0.[2.3.2.3D] .352.(f) 1)"503B"(\1.67>>Sstring");
while (m.find()) {
    System.out.println(Float.parseFloat(m.group()));
}

输出是:

26.0
2.3
2.4
1.67

字符串的

[2.3.2.3D]
部分被分成两个单独的浮点数


0
投票
String floatRegex = "[+-]?\\d*([.]?\\d+)";

0
投票

Jeff Holt 的答案更进一步...这里有一个正则表达式(几乎)与 Java 自己的数字格式匹配:

String integer  = "(?:[0-9](?:[_0-9]+[0-9])?)";
String mantissa = "(?:"+integer+"\\.?"+integer+"?|"+integer+"\\."+integer+")";
String exponent = "(?:[eE]"+integer+")";
String real     = "(?:"+mantissa+exponent+"?)";
String hex      = "(?:0[xX][0-9a-fA-F](?:[_0-9a-fA-F]+[0-9a-fA-F])?)";
String binary   = "(?:0[bB][01](?:[_01]+[01])?)";
String number   = "(?:[+-]?(?:"+real+"|"+hex+"|"+binary+"))";
Pattern.compile(number);

为了好玩,这是打印出来的最后一个字符串:

(?:[+-]?(?:(?:(?:(?:[0-9](?:[_0-9]+[0-9])?)\.?(?:[0-9](?:[_0-9]+[0-9])?)?|(?:[0-9](?:[_0-9]+[0-9])?)?\.(?:[0-9](?:[_0-9]+[0-9])?))(?:[eE](?:[0-9](?:[_0-9]+[0-9])?))?)|(?:0[xX][0-9a-fA-F](?:[_0-9a-fA-F]+[0-9a-fA-F])?)|(?:0[bB][01](?:[_01]+[01])?)))

这支持:

  • 整数(例如:1、70、-005、+1_000)
  • 浮点数(例如:1.、.70、-4.02、8e198_762)
  • 十六进制(例如:-0X9A_CD_004B,0xface),
  • 二进制(例如:0B01_11、0b11010011)
  • 数字之间用下划线

这不支持:

  • Java 式类型后缀(例如:10L、1e5f、20D)
  • 拒绝根据某种定义“太大”的数字
© www.soinside.com 2019 - 2024. All rights reserved.