問題描述
我有一個 numberDecimal EditText
我想使用正則表達(dá)式進(jìn)行驗(yàn)證.在驗(yàn)證中我想要的是:
I have a numberDecimal EditText
which I want to validate using a regular expression. In validation what I want is:
在小數(shù)點(diǎn)前,我要輸入的最大數(shù)字是三位,并且數(shù)字不應(yīng)以零開頭,如
2,23,342
等
小數(shù)點(diǎn)后我想輸入的最大位數(shù)是.1
, .3
, .6
等.
After the decimal point, the maximum digit I want to enter is one like .1
, .3
, .6
, etc.
所以我允許用戶輸入的數(shù)字是 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.
但在我的代碼中,發(fā)生的情況是:
它允許用戶在小數(shù)點(diǎn)前輸入多于三位的數(shù)字,例如
3456
、4444
、5555
和之后它不允許我輸入小數(shù)點(diǎn).
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.
它允許我在小數(shù)點(diǎn)前輸入0
作為數(shù)字的開始.
It allows me to enter 0
before the decimal point as the start of the digit.
那么為什么會發(fā)生這種情況,我使用的正則表達(dá)式有什么問題嗎?如果有人知道,請幫我解決這個問題.
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
中單獨(dú)檢查 dest
沒有任何意義;這就是該領(lǐng)域已經(jīng)存在的.將正則表達(dá)式匹配更改為針對 source
并且如果您只想檢查某些字符是否被接受到該字段中,這將是合適的.但是,您要檢查字段格式,而不僅僅是逐個字符地過濾輸入.這要復(fù)雜得多.
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
的內(nèi)容進(jìn)行更改時,系統(tǒng)都會調(diào)用過濾器的 filter
方法在實(shí)際進(jìn)行更改之前.它傳遞當(dāng)前字段內(nèi)容和建議的更改(可以是插入/追加、刪除或替換).更改由源 CharSequence source
(要添加到字段的字符(如果有))、源內(nèi)的范圍開始和結(jié)束索引(范圍不一定是 source
),一個 Spanned dest
(更改前的當(dāng)前字段內(nèi)容)和范圍 dstart 和 dest
內(nèi)的 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
繼續(xù)使用 source
).您需要檢查更改是否會導(dǎo)致可接受的字段,而不是像現(xiàn)在那樣檢查 dest
.為此,您將需要更復(fù)雜的邏輯.(特別注意,新字符可能用于插入末尾以外的位置;此外,當(dāng)用戶刪除字符以及添加字符時,將調(diào)用 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.)
實(shí)現(xiàn) TextWatcher
可能更容易.在它的 beforeTextChanged
方法中,您可以記錄當(dāng)前內(nèi)容,在它的 afterTextChanged
方法中,您可以檢查(使用正則表達(dá)式)內(nèi)容是否可接受,如果不是,恢復(fù)更改前的內(nèi)容.(不過,請確保更改之前的文本是可接受的.如果不是,請?zhí)鎿Q一些可接受的內(nèi)容——例如清除字段.否則您的代碼將進(jìn)入無限循環(huán),因?yàn)?TextWatcher
是當(dāng)您更正字段內(nèi)容時將再次調(diào)用.)
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.)
您的正則表達(dá)式也有錯誤:它允許前導(dǎo)零.這是修復(fù)此問題的改進(jìn)版本(并刪除了一組不必要的括號):
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;
}
});
這篇關(guān)于如何在 Android 中使用正則表達(dá)式的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網(wǎng)!