I have a numberDecimal EditText
which I want to validate using a regular expression. In validation what I want is:
Before the decimal point, the maximum digit I want to enter is three and the digit should not start with zero like
2,23,342
, etc.After the decimal point, the maximum digit I want to enter is one like
.1
,.3
,.6
, etc.
So the number that I allow the user to enter is like 2.1
, 32.5
, 444.8
, 564.9
, etc.
But in my code, what happens is:
It allows the user to enter more than a three digit number before the decimal point like
3456
,4444
,5555
and after that it doesn't allow me to enter a decimal point after that.It allows me to enter
0
before the decimal point as the start of the digit.
So why does this happen, is anything wrong in the regular expression I have used? If anyone knows, please help me to solve this.
Code I have used:
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
}
}
});
Maybe my implementation will help anyone:
You could try something like this:
^[1-9][0-9]{0,2}(\\.\\d)?$
. This should match any number which does not start with 0 (^[1-9]
) and is followed by at most two numbers ([0-9]{0,2}
). The regex also allows for an optional decimal value ((\\.\\d)?$
).That being said, ideally you should parse the string value to a
double
orfloat
and make what ever validations you need to make using the actual numerical value.To parse your
string
into adouble
value, you will need to use the Double.parseDouble(String s) like so:double myValue = Double.parseDouble(EditText.getText());
I tried your pattern using my code as following. It works perfectly as 2.1, 32.5, 444.8, 564.9 etc.
My code:
There's never any point in examining
dest
alone in anInputFilter
; that's what's already present in the field. Change the regular expression match to be againstsource
and it would be appropriate if you only wanted to check that certain characters were accepted into the field. However, you want to check field formatting, not just filter the input on a character-by-character basis. This is much more complex.Every time the user makes a change to the contents of
tempEditText
, the system calls your filter'sfilter
method before the change is actually made. It passes the current field contents and the proposed change (which can be insert/append, delete, or replace). The change is represented by a sourceCharSequence source
(the characters—if any—to be added to the field), range start and end indexes within the source (the range is not necessarily all ofsource
), aSpanned dest
(the current field contents before the change) and range dstart and dend indexes withindest
that are proposed to be replaced by the indicatedsource
range.The job of
filter
is to modify the change (if necessary) and return aCharSequence
to use (in its entirety) in place ofsource
(ornull
to go ahead and usesource
). Rather than checkingdest
as you are now doing, you will need to check whether the change will result in an acceptable field. To do this, you will need more complex logic. (Note, in particular, that the new character(s) may be intended for insert somewhere other than at the end; also,filter
will be called when the user is deleting characters as well as adding them.)It may be easier to implement a
TextWatcher
. In it'sbeforeTextChanged
method, you can record the current contents and in it'safterTextChanged
method, you can check (using a regular expression) whether the contents are acceptable and, if not, restore the before-the-change contents. (Make sure, though, that the text before the change was acceptable. If it isn't, substitute something acceptable—like clearing the field. Otherwise your code will go into an infinite loop because theTextWatcher
is going to be invoked again when you correct the field contents.)You also have an error in your regular expression: it allows a leading zero. Here's an improved version that fixes this problem (and removes one set of unnecessary parentheses):
(As an aside: you can use
\\d
instead of[0-9]
.)EDIT
Here's my edit of your edit:
You could just parse the number and check that it is < 1000 and that 10*number is an integer while num is not. It would probably be more readable too.