問題描述
我有一個 numberDecimal EditText
我想使用正則表達式進行驗證.在驗證中我想要的是:
I have a numberDecimal EditText
which I want to validate using a regular expression. In validation what I want is:
在小數點前,我要輸入的最大數字是三位,并且數字不應以零開頭,如
2,23,342
等
小數點后我想輸入的最大位數是.1
, .3
, .6
等.
After the decimal point, the maximum digit I want to enter is one like .1
, .3
, .6
, etc.
所以我允許用戶輸入的數字是 2.1
, 32.5
, 444.8
, 564.9
等.
So the number that I allow the user to enter is like 2.1
, 32.5
, 444.8
, 564.9
, etc.
但在我的代碼中,發生的情況是:
它允許用戶在小數點前輸入多于三位的數字,例如
3456
、4444
、5555
和之后它不允許我輸入小數點.
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.
它允許我在小數點前輸入0
作為數字的開始.
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.
我使用過的代碼:
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
}
}
});
推薦答案
在 InputFilter
中單獨檢查 dest
沒有任何意義;這就是該領域已經存在的.將正則表達式匹配更改為針對 source
并且如果您只想檢查某些字符是否被接受到該字段中,這將是合適的.但是,您要檢查字段格式,而不僅僅是逐個字符地過濾輸入.這要復雜得多.
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.
每次用戶對 tempEditText
的內容進行更改時,系統都會調用過濾器的 filter
方法在實際進行更改之前.它傳遞當前字段內容和建議的更改(可以是插入/追加、刪除或替換).更改由源 CharSequence source
(要添加到字段的字符(如果有))、源內的范圍開始和結束索引(范圍不一定是 source
),一個 Spanned dest
(更改前的當前字段內容)和范圍 dstart 和 dest
內的 dend 索引,建議替換為指定的來源
范圍.
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.
filter
的工作是修改更改(如果需要)并返回一個 CharSequence
以使用(全部)代替 source
(或 null
繼續使用 source
).您需要檢查更改是否會導致可接受的字段,而不是像現在那樣檢查 dest
.為此,您將需要更復雜的邏輯.(特別注意,新字符可能用于插入末尾以外的位置;此外,當用戶刪除字符以及添加字符時,將調用 filter
.)
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.)
實現 TextWatcher
可能更容易.在它的 beforeTextChanged
方法中,您可以記錄當前內容,在它的 afterTextChanged
方法中,您可以檢查(使用正則表達式)內容是否可接受,如果不是,恢復更改前的內容.(不過,請確保更改之前的文本是可接受的.如果不是,請替換一些可接受的內容——例如清除字段.否則您的代碼將進入無限循環,因為 TextWatcher
是當您更正字段內容時將再次調用.)
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]?)?$"
(順便說一句:您可以使用 \d
代替 [0-9]
.)
(As an aside: you can use \d
instead of [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;
}
});
這篇關于如何在 Android 中使用正則表達式的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!