25

我有一个 numberDecimal EditText,我想使用正则表达式对其进行验证。在验证中,我想要的是:

  1. 在小数点之前,我要输入的最大数字是三位,并且数字不应以零开头,例如2,23,342等。

  2. 小数点后,我要输入的最大位数是.1, .3,.6等。

所以我允许用户输入的数字是2.1, 32.5, 444.8,564.9等。

但在我的代码中,会发生什么:

  1. 它允许用户在小数点之前输入多于三位数的数字,例如3456, 44445555之后不允许我输入小数点。

  2. 它允许我0在小数点之前输入作为数字的开头。

那么为什么会发生这种情况,我使用的正则表达式有什么问题吗?如果有人知道,请帮我解决这个问题。

我用过的代码:

weightEditText.addTextChangedListener(new TextWatcher() 
{           
    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {               
    }           
    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {            
    }           
    @Override
    public void afterTextChanged(Editable s) 
    {
        Pattern mPattern = Pattern.compile("^([1-9][0-9]{0,2})?(\\.[0-9]?)?$");

        Matcher matcher = mPattern.matcher(s.toString());               
        if(!matcher.find())
        {
            weightEditText.setText(); // Don't know what to place                   
        }
    }
});
4

5 回答 5

25

在;中dest单独检查从来没有任何意义。InputFilter这就是该领域已经存在的。将正则表达式匹配更改为反对source,如果您只想检查某些字符是否被接受到该字段中,这将是合适的。但是,您要检查字段格式,而不仅仅是逐个字符地过滤输入。这要复杂得多。

每次用户对 的内容进行更改时,系统都会在实际进行更改之前tempEditText调用过滤器的filter方法。它传递当前字段内容和建议的更改(可以是插入/追加、删除或替换)。更改由源(要添加到字段的字符(如果有))、源内的范围开始和结束索引(范围不一定全部为)、a (更改前的当前字段内容)表示范围内的 dstart 和 dend 索引建议替换为指定的范围。CharSequence sourcesourceSpanned destdestsource

的工作filter是修改更改(如有必要)并返回 aCharSequence以使用(全部)代替source(或null继续使用source)。dest您需要检查更改是否会导致可接受的字段,而不是像现在所做的那样检查。为此,您将需要更复杂的逻辑。(请特别注意,新字符可能用于插入末尾以外的其他位置;此外,filter当用户删除字符以及添加字符时将调用它们。)

实现一个TextWatcher. 在 it'sbeforeTextChanged方法中,您可以记录当前内容,在 it'safterTextChanged方法中,您可以检查(使用正则表达式)内容是否可接受,如果不可接受,则恢复更改前的内容。(但请确保更改之前的文本是可接受的。如果不是,请替换一些可接受的内容 - 例如清除字段。否则您的代码将进入无限循环,因为TextWatcher当您更正时将再次调用字段内容。)

您的正则表达式中也有错误:它允许前导零。这是修复此问题的改进版本(并删除了一组不必要的括号):

"^([1-9][0-9]{0,2})?(\\.[0-9]?)?$"

(顺便说一句:您可以使用\\d代替[0-9]。)

编辑

这是我对您的编辑的编辑:

weightEditText.addTextChangedListener(new TextWatcher() 
{           
    private static final Pattern sPattern
        = Pattern.compile("^([1-9][0-9]{0,2})?(\\.[0-9]?)?$");

    private CharSequence mText;

    private boolean isValid(CharSequence s) {
        return sPattern.matcher(s).matches();
    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count){
    }           

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count,
            int after){
        mText = isValid(s) ? new CharSequence(s) : "";
    }           

    @Override
    public void afterTextChanged(Editable s) 
    {
        if (!isValid(s))
        {
            weightEditText.setText(mText);
        }
        mText = null;
    }
});
于 2012-04-26T22:39:26.953 回答
2

也许我的实现会帮助任何人:

    etRepeaterCallsign.addTextChangedListener(new TextWatcher() {
        private final Pattern sPattern
                = Pattern.compile("^([A-Z]{0,2})?(\\d)?([A-Z-]{0,5})"); // ^([1-9][0-9]{0,2})?(\\.[0-9]?)?$

        private CharSequence mText;

        private boolean isValid(CharSequence s) {
            return sPattern.matcher(s).matches();
        }

        @Override
        public void beforeTextChanged(CharSequence r, int start, int count,
                                      int after) {
            mText = r.toString();
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            bIsEdit = true;
        }
        @Override
        public void afterTextChanged(Editable s) {
            etRepeaterCallsign.removeTextChangedListener(this);

            int iCursorPosition = etRepeaterCallsign.getSelectionStart();
            etRepeaterCallsign.setText("");
            if (isValid(s))
                etRepeaterCallsign.append(s);
            else
                etRepeaterCallsign.append(mText);

            etRepeaterCallsign.setSelection(iCursorPosition);

            etRepeaterCallsign.addTextChangedListener(this);

        }
    });
于 2014-12-26T19:27:16.480 回答
1

您可以只解析数字并检查它是否 < 1000 并且 10*number 是一个整数,而 num 不是。它也可能更具可读性。

于 2012-04-26T05:56:39.463 回答
1

我使用以下代码尝试了您的模式。它可以完美地用作 2.1、32.5、444.8、564.9 等。

我的代码:

public class WebPush extends Activity {  
    EditText editTxt;
    private TextView regresult;  

    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main); 

        editTxt = (EditText) findViewById(R.id.editID);
        regresult = (TextView) findViewById(R.id.txtID);

        String urName = editTxt.getText().toString();
        editTxt.addTextChangedListener(new TextWatcher() {

            @Override
            public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
            }

            @Override
            public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,int arg3) {
            }       

            @Override
            public void afterTextChanged(Editable s) {
                if (editTxt.getText().toString().matches("(^([0-9]{0,3})?)(\\.[0-9]{0,1})?$"))
                {
                    regresult.setText("");
                }
                else
                {
                    regresult.setText("invalid number");
                }
            }
        });
    }
}
于 2012-04-26T06:27:28.370 回答
0

你可以尝试这样的事情:^[1-9][0-9]{0,2}(\\.\\d)?$. 这应该匹配任何不以 0 ( ^[1-9]) 开头且后跟最多两个数字 ( [0-9]{0,2}) 的数字。正则表达式还允许使用可选的十进制值 ( (\\.\\d)?$)。

话虽如此,理想情况下,您应该将字符串值解析为 a doubleorfloat并使用实际数值进行您需要进行的任何验证。

要将您的值解析string为一个double值,您需要像这样使用Double.parseDouble(String s)double myValue = Double.parseDouble(EditText.getText());

于 2012-04-26T05:57:49.113 回答