我有一个numberDecimal EditText
,我想用正则表达式验证它。在验证中我想要的是:
在小数点之前,我要输入的最大数字是3,数字不应该像2,23,342
那样以零开头等。
小数点后,我想输入的最大数字是.1
,.3
,.6
等。
因此,我允许用户输入的数字类似于2.1
,32.5
,444.8
,564.9
等。
但在我的代码中,会发生什么:
它允许用户在小数点之前输入超过三位数的数字,如3456
,4444
,5555
,之后它不允许我之后输入小数点。
它允许我在小数点前输入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
}
}
});
答案 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)?$
)。
话虽如此,理想情况下,您应该将字符串值解析为double
或float
,并使用实际数值制作您需要进行的验证。
要将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");
}
}
});
}
}