本文介绍了如何在 Android 中使用正则表达式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 numberDecimal EditText 我想使用正则表达式进行验证.在验证中我想要的是:

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

  1. 在小数点前,我要输入的最大数字是三位,并且数字不应以零开头,如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.

但在我的代码中,发生的情况是:

  1. 它允许用户在小数点前输入多于三位的数字,例如 345644445555 和之后它不允许我输入小数点.

  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.

它允许我在小数点前输入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 中使用正则表达式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 12:22