25

EditText正規表現を使用して検証したいnumberDecimalがあります。検証では、私が欲しいのは次のとおりです。

  1. 小数点の前に、入力したい最大桁は 3 桁であり、桁は2,23,342などのようにゼロで開始しないでください。

  2. 小数点の後に、入力したい最大桁は.1.3.6などです。

したがって、ユーザーが入力できる番号は、、、、2.1などです32.5444.8564.9

しかし、私のコードでは、次のようになります。

  1. ユーザーは、、のよう3456に小数点の前に 3 桁以上の数字を入力できます。その後、小数点を入力することはできません。44445555

  2. 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                   
        }
    }
});
4

5 に答える 5

25

;destで単独で調べても意味がありません。InputFilterそれは現場にすでに存在するものです。source特定の文字がフィールドに受け入れられたことのみを確認したい場合は、正規表現の一致を反対に変更します。ただし、文字ごとに入力をフィルター処理するだけでなく、フィールドの書式設定を確認する必要があります。これははるかに複雑です。

ユーザーが の内容を変更するたびに、変更が実際に行われる前にtempEditText、システムはフィルターのfilterメソッドを呼び出します。現在のフィールドの内容と提案された変更 (挿入/追加、削除、または置換) を渡します。変更は、ソース(フィールドに追加される文字 (存在する場合))、ソース内の範囲の開始インデックスと終了インデックス (範囲が必ずしもすべてではない)、a (変更前の現在のフィールドの内容) によって表されます。その範囲内の dstart および dend インデックスは、指定された範囲に置き換えることが提案されています。CharSequence sourcesourceSpanned destdestsource

の仕事はfilter、(必要に応じて) 変更を修正し、 a を返してCharSequence(全体を) の代わりに使用するsource(またはnull先に進んで を使​​用するsource) ことです。現在行っているように確認するのではなくdest、変更が許容可能なフィールドになるかどうかを確認する必要があります。これを行うには、より複雑なロジックが必要になります。(特に、新しい文字は最後以外の場所に挿入することを意図している可能性があることに注意してください。また、filterユーザーが文字を追加するだけでなく削除するときにも呼び出されます。)

を実装する方が簡単かもしれませんTextWatcher。そのbeforeTextChanged方法では、現在の内容を記録できます。そのafterTextChanged方法では、内容が受け入れられるかどうかを (正規表現を使用して) チェックし、受け入れられない場合は変更前の内容に戻すことができます。(ただし、変更前のテキストが許容できるものであることを確認してください。そうでない場合は、フィールドをクリアするなど、許容できるものに置き換えてください。そうしないと、TextWatcher修正時に が再度呼び出されるため、コードが無限ループに陥ります。フィールドの内容。)

正規表現にもエラーがあります。先行ゼロが許可されています。この問題を修正した (そして不要な括弧を 1 セット削除した) 改良版を次に示します。

"^([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;
    }
});
于 2012-04-26T22:39:26.953 に答える
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);

        }
    });
于 2014-12-26T19:27:16.480 に答える
1

数値を解析して、それが < 1000 であること、および 10*number が整数であり、num がそうでないことを確認するだけです。それもおそらくより読みやすいでしょう。

于 2012-04-26T05:56:39.463 に答える
1

次のように私のコードを使用してパターンを試しました。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");
                }
            }
        });
    }
}
于 2012-04-26T06:27:28.370 に答える
0

次のようなことを試すことができます^[1-9][0-9]{0,2}(\\.\\d)?$。これは、0 で始まらず ( ^[1-9])、その後に最大 2 つの数字が続く任意の数字 ( ) と一致する必要があり[0-9]{0,2}ます。正規表現では、オプションの 10 進数値 ( (\\.\\d)?$) も使用できます。

そうは言っても、理想的には、文字列値をdoubleorに解析floatし、実際の数値を使用して必要な検証を行う必要があります。

あなたstringを値に解析するには、次のようにDouble.parseDouble(String s)doubleを使用する必要があります。double myValue = Double.parseDouble(EditText.getText());

于 2012-04-26T05:57:49.113 に答える