Regex for DocumentFilter to match all decimal numb

2020-04-21 06:37发布

问题:

Qestion First: I need to regex to match 111 or 111. or 111.111 (just aritrarty numbers) for a DocumentFilter. I need the user to be able to input 111. with a decimal and nothing afterwards. Can't seem to get it right.

All the Regexes I find all match just all decimal numbers i.e.

12343.5565
32.434
32

Like this regex

^[0-9]*(\\.)?[0-9]+$

Problem is, I need the regex for a DocumentFilter so the input can only be numbers with/without a decimal point. But the catch is it also needs to match

1223.

So the user can input the decimal into the text field. So basically I need to regex to match

11111         // all integer
11111.        // all integers with one decimal point and nothing after
11111.1111    // all decimal numbers

The pattern I have so far is the one above. Here is a test program (For Java users)

The patter can be input in the this line

 Pattern regEx = Pattern.compile("^[0-9]*(\\.)?[0-9]+$");

If the regex fits the bill, then you will be able to input 111 or 111. or 111.111.

Run it :)

import java.awt.GridBagLayout;
import java.util.regex.*;
import javax.swing.*;
import javax.swing.text.*;

public class DocumentFilterRegex {

    JTextField field = new JTextField(20);

    public DocumentFilterRegex() {

        ((AbstractDocument) field.getDocument()).setDocumentFilter(new DocumentFilter() {
            Pattern regEx = Pattern.compile("^[0-9]*(\\.)?[0-9]+$");

            @Override
            public void insertString(DocumentFilter.FilterBypass fb, int off, String str, AttributeSet attr)
                    throws BadLocationException {
                Matcher matcher = regEx.matcher(str);
                if (!matcher.matches()) {
                    return;
                }
                super.insertString(fb, off, str, attr);
            }

            @Override
            public void replace(DocumentFilter.FilterBypass fb, int off, int len, String str, AttributeSet attr)
                    throws BadLocationException {
                Matcher matcher = regEx.matcher(str);
                if (!matcher.matches()) {
                    return;
                }
                super.replace(fb, off, len, str, attr);
            }
        });

        JFrame frame = new JFrame("Regex Filter");
        frame.setLayout(new GridBagLayout());
        frame.add(field);
        frame.setSize(300, 150);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);

    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new DocumentFilterRegex();
            }
        });
    }
}

EDIT:

My original assumption that the str passed to the methods were the entire document String, so I was confused about why the answers didn't work. I realized it was only the attempted inserted portion of the String that is passed.

That said, the answers work perfect, if you get the entire document String from the FilterBypass and check the regex against the entire document String. Something like

@Override
public void insertString(DocumentFilter.FilterBypass fb, int off, String str, AttributeSet attr)
        throws BadLocationException {

    String text = fb.getDocument().getText(0, fb.getDocument().getLength() - 1);
    Matcher matcher = regEx.matcher(text);
    if (!matcher.matches()) {
        return;
    }
    super.insertString(fb, off, str, attr);
}

回答1:

The following regex might work for you:

^[0-9]+[.]?[0-9]{0,}$

The quantifier {0,} would match zero or more digits.



回答2:

I would use the regex

^\d+\.?\d*$

Explanation and demonstration here: http://regex101.com/r/iM3nX5

Make sure you double-escape the escape sequences, like this:

Pattern regEx = Pattern.compile("^\\d+\\.?\\d*$");