Regex in PreviewTextInput: only decimals between 0

2019-09-09 22:00发布

问题:

I'd like to have a regex, which only allows digits between 0.0 and 1.0 in a textbox.

BUT it should be in the method PreviewTextInput (C#, WPF project)

So the normal regex doesn't work

Regex regex = new Regex(@"^0|0.0|0\.[0-9]*|1\.0|1$");

I've found a regex, which allows all decimals in the PreviewTextInput method:

Regex regex = new Regex("^[.][0-9]+$|^[0-1.]*[.,]{0,1}[0-9]*$");

How can a change this regex to only accept decimals between 0-1?

Thanks.

My method for decimals:

private void tb_PreviewTextInput(object sender, TextCompositionEventArgs e)
    {
        Regex regex = new Regex("^[.][0-9]+$|^[0-1.]*[.,]{0,1}[0-9]*$");
        e.Handled = !regex.IsMatch((sender as TextBox).Text.Insert((sender as TextBox).SelectionStart, e.Text));
    }

My method for decimals between 0-1 (doesn't work):

        private void tb_Surface_PreviewTextInput(object sender, TextCompositionEventArgs e)
    {
        Regex regex = new Regex(@"^(0?\.[0-9]+|1\.0)$");
        e.Handled = !regex.IsMatch(e.Text);
       // e.Handled = !regex.IsMatch((sender as TextBox).Text.Insert((sender as TextBox).SelectionStart, e.Text));

    }

回答1:

@"^(0(?:\.\d+)?|1(?:\.0+)?)$"

0 and 1 also can be matched,if you don't want match them,and must have any digits after dot ,you can use

@"^(0\.\d+|1\.0+)$"

The code below is what you want,and you need to remove the last dot when the textbox lost focus,such as str.Trim('.')

private void tb_Surface_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
    var patten = @"^(0(\.\d*)?|1(\.0*)?)$";
    Regex regex = new Regex(patten);
    e.Handled = !regex.IsMatch(e.Text);
    // e.Handled = !regex.IsMatch((sender as TextBox).Text.Insert((sender as TextBox).SelectionStart, e.Text));
}


回答2:

You may try this regex.

@"^(?:0?\.[0-9]+|1\.0)$"


回答3:

About @"^0|0.0|0\.[0-9]*|1\.0|1$": there are two mistakes:

1) one of the dot is not escaped, so it can match any characters.
2) The ^ and $ are only respectively in the first and last branches of your alternation, but are not in factor with each branch. To do that you must put all branches in a non capturing group.

About "^[.][0-9]+$|^[0-1.]*[.,]{0,1}[0-9]*$": the first branch is ok, the second branch is false.

1) [0-1.]* that can be written [01.]* (there is no characters between 0 and 1, no need to put a range) allow any combination of 0, 1 and .: 1111111111, 10100010 or 1.00.111... Not sure that allowing the dot here is a good idea.
2) [.,]{0,1} that can be written [.,]?: why this time you want to allow the comma?
3) [.,]{0,1}[0-9]*$ if the dot (or the comma) is optional, this subpattern can match any integer because of the [0-9]*.

I think you must consider using non-capturing groups to build your pattern. Starting from your first pattern seems to be the best option. Anyway, the first job is to clearly define what are the allowed formats.