如何在Android中使用正则表达式

时间:2012-04-26 05:52:13

标签: android regex android-edittext

我有一个numberDecimal EditText,我想用正则表达式验证它。在验证中我想要的是:

  1. 在小数点之前,我要输入的最大数字是3,数字不应该像2,23,342那样以零开头等。

  2. 小数点后,我想输入的最大数字是.1.3.6等。

  3. 因此,我允许用户输入的数字类似于2.132.5444.8564.9等。

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

    1. 它允许用户在小数点之前输入超过三位数的数字,如345644445555,之后它不允许我之后输入小数点。

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

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

      我使用的代码:

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

5 个答案:

答案 0 :(得分:23)

dest中单独检查InputFilter是绝对没有意义的。这就是现场已经存在的东西。将正则表达式匹配更改为source,如果您只想检查字段中是否接受了某些字符,那么它是合适的。但是,您要检查字段格式,而不仅仅是逐个字符地过滤输入。这要复杂得多。

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

filter的工作是修改更改(如有必要)并返回CharSequence以使用(完整)代替source(或null继续使用source)。您不必像现在一样检查dest,而是需要检查更改是否会产生可接受的字段。要做到这一点,您将需要更复杂的逻辑。 (特别注意,新字符可能用于插入到最后的某个位置;同样,当用户删除字符以及添加字符时,将调用filter。)

实施TextWatcher可能更容易。在它的beforeTextChanged方法中,您可以记录当前内容,并且在其afterTextChanged方法中,您可以检查(使用正则表达式)内容是否可接受,如果不是,则恢复之前的内容改变内容。 (但请确保更改前的文本是可以接受的。如果不是,请替换可接受的内容 - 比如清除字段。否则您的代码将进入无限循环,因为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;
    }
});

答案 1 :(得分: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);

        }
    });

答案 2 :(得分:1)

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

答案 3 :(得分:0)

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

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

要将string解析为double值,您需要像double myValue = Double.parseDouble(EditText.getText());一样使用{{1}}

答案 4 :(得分:0)

我使用我的代码尝试了你的模式,如下所示。它完美地工作在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");
                }
            }
        });
    }
}