【问题标题】:Regex to find a float正则表达式查找浮点数
【发布时间】:2011-07-19 21:47:10
【问题描述】:

我以前从未使用过正则表达式,但这个 java 函数需要它(此处显示:How to set Edittext view allow only two numeric values and two decimal values like ##.##

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

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

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

这样做的正确方法是什么?谢谢

【问题讨论】:

    标签: java regex


    【解决方案1】:

    试试这个:

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

    【讨论】:

    • 嗯,由于某种原因,每当我输入小数时,它都会退格...所以 1234.5 变成 1235。我认为这不是正则表达式的错,所以谢谢 :)
    • 这是正则表达式的错误,对不起。让我解决它。
    • 我不允许像 2. 这样的字符串在点后没有任何内容,因为它通常会写成 2.0,但它永远不会让你到达 2.0,所以我改变了它现在允许2.
    • AAA而且,我刚刚注意到它不会让我输入前面没有“0”的“.5”。
    • 这匹配空字符串,或单个点,或本身的加号或减号。
    【解决方案2】:

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

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

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

    【讨论】:

    • 我希望它不允许人们输入字母,这就是我更喜欢正则表达式解决方案的原因。不过我可能最终会按照你的方式去做,这是我最初的计划。
    • 为什么 Float.parseFloat() 允许字母作为浮点数通过? 1.f3 并不是一个有效的浮点数。同样在这种情况下,您可以进行其他检查,例如确保解析的 Float 可用。大概 Float.INFINITY 不应该被允许,尽管正则表达式和 parseFloat 都会让它作为有效的浮点数通过 - 但在 parseFloat 的情况下你可以检查它。
    • 我知道这会告诉我框中的值是否为浮点数,但我希望框中的值永远不会不是浮点数(如果这有任何意义)跨度>
    • @Jdban101:这是一个单独的问题。您需要先查看它是否是浮动的。如果它不是浮点数,请将文本框或其他内容空白。
    • @jeff 任何曾经存在的 GUI 框架都需要某种属性更改事件处理程序。 Android的edittext有TextView.addTextChangedListener(TextWatcher)。
    【解决方案3】:

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

    这是公认的答案:

    String 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+$";
      

      【讨论】:

        【解决方案5】:

        这个答案来自 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] 部分被分成两个独立的浮点数

        【讨论】:

          【解决方案6】:
          String floatRegex = "[+-]?\\d*([.]?\\d+)";
          

          【讨论】:

            猜你喜欢
            • 2012-08-16
            • 2012-09-20
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-11-21
            • 2014-04-25
            相关资源
            最近更新 更多