在DocumentFilter中使用正则表达式来解决JTextField问题 [英] Trouble using regex in DocumentFilter for JTextField

查看:111
本文介绍了在DocumentFilter中使用正则表达式来解决JTextField问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 JTextField 上使用 DocumentFilter ,用于输入员工拥有的时间工作。过滤器是为了确保输入限制只有4个字符长,并且只允许数字。可以使用或不使用小数,但只允许输入一次,输入小数后,应该只允许一个小数。意思是9.5或10.5应该被接受而8.45不是。

I am using a DocumentFilter on a JTextField which is used to enter in the amount of time an employee has worked. the filter is to ensure that the limit of input is only 4 characters long and to only allow numbers. A decimal may or may not be used but should only be allowed to be entered once, once a decimal is entered, there should only allow for one more number. Meaning 9.5 or 10.5 should be accepted and 8.45 is not.

到目前为止,我能够得到大约一半的所需功能。最多可输入4个字符,仅允许数字。后者是使用 replaceAll([^ 0-9。],)方法完成的。

So far I am able to get about half of the total desired functionality. No more than 4 characters can be entered and only digits are allowed. The latter is accomplished using the replaceAll("[^0-9.]", "") method.

我花了很多时间观看教程,阅读文档和相关问题,例如这个这个,特别是这个,但是似乎无法让正则表达式完全执行。有一点特别是我无法弄清楚为什么 [^ 0-9] 的正则表达式成功只允许数字,但是 ^ \\\\ 除非作为 [\\d]

I've spent a lot of time watching tutorials, reading documentation and related questions such as this, this, and especially this, but can't seem to get a regex to perform fully. One thing in particular than I can't figure out is why exactly a regex of [^0-9] will successfully only allow digits, but ^\\d wont unless enclosed as a character class such as [\\d]

我的过滤器代码如下:

import java.awt.Toolkit;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;

public class TimeWorkedFilter extends DocumentFilter {

    private int maxCharacters;    

    public TimeWorkedFilter(int maxChars) {
        maxCharacters = maxChars;
    }
//"[^0-9.]
    public void insertString(FilterBypass fb, int offs, String str, AttributeSet a)
            throws BadLocationException {

        if ((fb.getDocument().getLength() + str.length()) <= maxCharacters)
            super.insertString(fb, offs, str.replaceAll("[^0-9.]", ""), a);
        else
            Toolkit.getDefaultToolkit().beep();
    }

    public void replace(FilterBypass fb, int offs, int length, String str, AttributeSet a)
            throws BadLocationException {

        if ((fb.getDocument().getLength() + str.length()
                - length) <= maxCharacters)
            super.replace(fb, offs, length, str.replaceAll("[^0-9.]", ""), a);
        else
            Toolkit.getDefaultToolkit().beep();
    }
}


推荐答案


我无法弄清楚为什么正是一个[^ 0-9]的正则表达式将成功只允许数字

"I can't figure out is why exactly a regex of [^0-9] will successfully only allow digits"

str 传递给您的重写方法(在输入方面)只是一个字符,因为每次键入一个字符时都会调用过滤方法。正则表达式 [^ 0-9] 表示不是数字。因此,当您执行 str.replaceAll([^ 0-9。],)时,您将获得过滤器权限以将字符插入文本字段,只要它是一个数字,否则它将添加一个空字符/字符串,使用户无法输入字母的效果。

The str passed to your overridden methods (in terms of typing) is only a single character, as the filter methods are called every time you type in a character. The regex [^0-9] means not numbers. So when you do str.replaceAll("[^0-9.]", ""), you are giving the filter permission to insert the character to the text field, as as long as it is a number, other wise it will add an empty character/string, giving the effect of the user not being able to enter a letter.

那正如所说的那样,对于真正的问题

That being said, as for the real question


过滤器是为了确保输入的限制只有4个字符长并且只允许可以使用也可以不使用十进制,但只允许输入一次,输入一个十进制后,应该只允许一个数字。意思是9.5或10.5应该被接受而8.45不是。

" the filter is to ensure that the limit of input is only 4 characters long and to only allow numbers. A decimal may or may not be used but should only be allowed to be entered once, once a decimal is entered, there should only allow for one more number. Meaning 9.5 or 10.5 should be accepted and 8.45 is not."

如上所述,传递给方法的 str 是一个字符,所以如果您尝试将完整的正则表达式传递给 str.replaceAll()以匹配说 8.9 ,则不会工作。 replaceAll()中的正则表达式只是检查单个字符(在本例中)。

As mentioned above, the str passed to the method is a single character, so if you try to pass a complete regex to the str.replaceAll() to match say 8.9, it won't work. The regex in the replaceAll() is meant to just check the single character (in this case).

你可以做什么而不是从文档中获取文本,将 str 连接到文档,看看是否总文本匹配()完整的正则表达式。类似

What you can do instead it get the text from the document, concatenate the str to the document and see if the total text matches() a complete regex. Something like

public void replace(FilterBypass fb, int offs, int length, String str, AttributeSet a)
        throws BadLocationException {

    String text = fb.getDocument().getText(0, fb.getDocument().getLength());
    text += str;
    if ((fb.getDocument().getLength() + str.length()
            - length) <= maxCharacters && text.matches("^[0-9]+[.]?[0-9]{0,1}$")) {
        super.replace(fb, offs, length, str, a);
    } else {
        Toolkit.getDefaultToolkit().beep();
    }
}

不确定这是否是你想要的正确的正则表达式。正则表达式不是我的强项。我从这个问题获得了正则表达式

Not sure if that's the exact regex your looking for. Regex is not my forte. I got the regex from this question

这篇关于在DocumentFilter中使用正则表达式来解决JTextField问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆