Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use regular expression in Android

Tags:

I have a numberDecimal EditText which I want to validate using a regular expression. In validation what I want is:

  1. 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.

  2. 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:

  1. 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.

  2. 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                            }     } }); 
like image 223
AndroidDev Avatar asked Apr 26 '12 05:04

AndroidDev


People also ask

What is regex Android?

↳ java.util.regex.Pattern. A compiled representation of a regular expression. A regular expression, specified as a string, must first be compiled into an instance of this class. The resulting pattern can then be used to create a Matcher object that can match arbitrary character sequences against the regular expression.

What is difference [] and () in regex?

[] denotes a character class. () denotes a capturing group. [a-z0-9] -- One character that is in the range of a-z OR 0-9.

What does '$' mean in regex?

$ means "Match the end of the string" (the position after the last character in the string).

What are regular expressions in Java?

Java - Regular Expressions. Java provides the java.util.regex package for pattern matching with regular expressions. Java regular expressions are very similar to the Perl programming language and very easy to learn. A regular expression is a special sequence of characters that helps you match or find other strings or sets of strings,...

Should I use a regex for non-@?

I wouldn't use one just for this though - only use regular expressions where you're really interested in pattern matching. If you want to use a regex for "at least one non-@, following by @, followed by at least one non-@" you could use:

How do regular expressions work with captures?

Leveraging the power of regular expressions changes this process to allow a properly formed regex to carry over parts of the original text into the replacement text! Using captures allows us to hold on to chunks of the original text and then easily use them in the replacement text.

Which methods accept a regular expression as the first argument?

These methods accept a regular expression as the first argument. Matcher Class − A Matcher object is the engine that interprets the pattern and performs match operations against an input string. Like the Pattern class, Matcher defines no public constructors. You obtain a Matcher object by invoking the matcher () method on a Pattern object.


1 Answers

There's never any point in examining dest alone in an InputFilter; that's what's already present in the field. Change the regular expression match to be against source 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's filter 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 source CharSequence 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 of source), a Spanned dest (the current field contents before the change) and range dstart and dend indexes within dest that are proposed to be replaced by the indicated source range.

The job of filter is to modify the change (if necessary) and return a CharSequence to use (in its entirety) in place of source (or null to go ahead and use source). Rather than checking dest 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's beforeTextChanged method, you can record the current contents and in it's afterTextChanged 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 the TextWatcher 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):

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

(As an aside: you can use \\d instead of [0-9].)

EDIT

Here's my edit of your edit:

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;     } }); 
like image 177
Ted Hopp Avatar answered Oct 12 '22 00:10

Ted Hopp