Подтвердить что ты не робот

Как использовать регулярное выражение в android

У меня есть numberDecimal EditText, который я хочу проверить с помощью регулярного выражения. При проверке я хочу.

  • До десятичной точки максимальная цифра, которую я хочу ввести, равна трем, и цифра не должна начинаться с нуля, как 2,23,342 и т.д.

  • После десятичной точки максимальная цифра, которую я хочу ввести, равна 1,.3,.6 и т.д.

Таким образом, число, которое я разрешаю пользователю вводить, равно 2.1, 32.5, 444.8, 564.9 и т.д.

Но в моем коде что происходит -

  • Это позволяет пользователю вводить более трехзначное число перед десятичной точкой, например 3456, 4444, 5555, и после этого после этого оно не позволяет мне вводить десятичную точку.

  • Это позволяет мне вводить 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(); // dont know what to place                    
            }
        }
    });
4b9b3361

Ответ 1

Никогда не нужно рассматривать только dest в InputFilter; что то, что уже присутствует в поле. Измените соответствие регулярного выражения на source, и было бы уместно, если бы вы только хотели проверить, что определенные символы были приняты в поле. Тем не менее, вы хотите проверить форматирование полей, а не просто фильтровать ввод посимвольной основе. Это намного сложнее.

Каждый раз, когда пользователь вносит изменения в содержимое tempEditText, система вызывает ваш фильтр filter до того, как будет произведено изменение. Он передает текущее содержимое поля и предлагаемое изменение (которое может быть вставлено/добавлено, удалено или заменено). Изменение представлено источником CharSequence source (символы — если any — быть добавленным в поле), индексы начала и конца диапазона в источнике (диапазон не обязательно все source), a Spanned dest (текущее содержимое поля перед изменением) и диапазоны dstart и dend indexes в пределах dest, которые предлагаются для замены указанным диапазоном source.

Задача filter состоит в том, чтобы изменить изменение (если необходимо) и вернуть CharSequence для использования (в полном объеме) вместо source (или null для продолжения и использования source). Вместо проверки dest, как вы сейчас это делаете, вам нужно будет проверить, приведет ли изменение к допустимому полю. Для этого вам понадобится более сложная логика. (Обратите внимание, в частности, что новый символ может быть предназначен для вставки где-то иначе, чем в конце, а также, filter будет вызываться, когда пользователь удаляет символы, а также добавляет их.)

Может быть проще реализовать TextWatcher. В этом методе beforeTextChanged вы можете записать текущее содержимое и в нем afterTextChanged метод, вы можете проверить (используя регулярное выражение), приемлемо ли содержимое и если нет, восстановить содержимое до изменения. (Убедитесь, что текст перед изменением был приемлемым.Если это не так, замените что-то приемлемое &mdash, как очистка поля. В противном случае ваш код перейдет в бесконечный цикл, потому что снова будет вызываться TextWatcher когда вы исправляете содержимое поля.)

У вас также есть ошибка в вашем регулярном выражении: она позволяет вести нулевой уровень. Здесь улучшенная версия, которая устраняет эту проблему (и удаляет один набор ненужных круглых скобок):

"^([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;
    }
});

Ответ 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);

        }
    });

Ответ 3

Вы можете просто проанализировать номер и проверить, что он равен < 1000, и это число 10 * является целым числом, а num - нет. Вероятно, это было бы более читаемым.

Ответ 4

Вы можете попробовать что-то вроде этого: ^[1-9][0-9]{0,2}(\\.\\d)?$. Это должно соответствовать любому числу, которое не начинается с 0 (^[1-9]), а за ним следует не более двух чисел ([0-9]{0,2}). Регулярное выражение также допускает необязательное десятичное значение ((\\.\\d)?$).

В идеале вы должны проанализировать строковое значение на double или float и сделать все, что нужно сделать, используя фактическое числовое значение.

Чтобы проанализировать ваш string в значение double, вам нужно будет использовать Double.parseDouble(String s) так: double myValue = Double.parseDouble(EditText.getText());

Ответ 5

Я попробовал свой шаблон, используя свой код, как показано ниже. Он отлично работает как 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");
                }
            }
        });
    }
}