Wpf 文本框的正则表达式浮点数格式化程序
Regex floating point Number Formatter for Wpf Textbox
我今天第一次看到正则表达式。我的 WPF 文本框需要一个正则表达式格式化程序,如下所示:
12345,1234
我需要一个小数分隔符,例如“,”或“。”负数应该被允许。
所以你可以这样写:
230,56 / 1289,4 / -1.9 / 63478,1252 / 0.3265
这应该是不可能的:
086,344 / 34,7000 / 1.0×10−4
如果后面没有逗号,则开头为 0 是不允许的。如果逗号后的最后一个数字是 0 也是不好的。没有科学记数法。
我找到了简单整数值的代码:
private void Int_PreviewTextInput(object sender, System.Windows.Input.TextCompositionEventArgs e)
{
// Just Ints
Regex regex = new Regex("[^0-9]+");
e.Handled = regex.IsMatch(e.Text);
}
那么像我描述的那样的浮点数格式化程序是什么样子的?
我对您的要求解读如下:
- 字符串前面可能有一个可选的“-”字符
- 在小数点分隔符之前,应该有一个“0”,或者任何不以“0”开头的数字。
- 在小数点分隔符之后,应该有一个“0”,或者任何不以“0”结尾的数字。
这直接转换为以下正则表达式:
@"^-?(0|[1-9]\d*)[,\.](0|\d*[1-9])$"
如果允许没有小数点分隔符的数字(问题对此不清楚),则从分隔符开始的部分将是可选的,即
@"^-?(0|[1-9]\d*)([,\.](0|\d*[1-9]))?$"
根据您的要求,以下模式似乎可行:
^-?(?!.*0$)(?!0\d)\d+(?:[,.]\d+)?$
见demo
^
- 开始字符串 ancor。
-?
- 允许使用负值的可选连字符。
(?!.*0)
- 否定前瞻以防止以 0
. 结尾的字符串
(?!0\d)
- 否定前瞻以防止以 0
和数字开头的字符串。
\d+
- 任何数字至少出现一次。
(?:
- 打开非捕获组。
[,.]
- 逗号或点作为十进制分隔符。
\d+
- 一个或多个数字。
)?
- 关闭非捕获组并使其可选。
$
- 结束字符串锚点。
如果您想检查用户是否输入了有效的十进制数,.NET 为您提供了可读且简单的验证方法。只需使用 decimal.TryParse
本着“为工作使用正确的工具”的精神,您不应使用正则表达式进行此类验证。
就像这样使用它:
var parseOk = decimal.TryParse(textBlock.Text, out _); // here I used _ as parameter name, as it is not relevant
if(! parseOk)
{
// validation failed
}
为了控制小数分隔符的处理方式,您可以使用重载方法:
public static bool TryParse (string s, System.Globalization.NumberStyles style,
IFormatProvider provider, out decimal result);
此外,您还必须决定数字的存储方式(浮点数、十进制数或双精度数)。幸运的是,这些类型中的每一种都公开了两个静态方法:Parse
和 TryParse
- 我鼓励您阅读它们。
我今天第一次看到正则表达式。我的 WPF 文本框需要一个正则表达式格式化程序,如下所示: 12345,1234 我需要一个小数分隔符,例如“,”或“。”负数应该被允许。 所以你可以这样写:
230,56 / 1289,4 / -1.9 / 63478,1252 / 0.3265
这应该是不可能的:
086,344 / 34,7000 / 1.0×10−4
如果后面没有逗号,则开头为 0 是不允许的。如果逗号后的最后一个数字是 0 也是不好的。没有科学记数法。
我找到了简单整数值的代码:
private void Int_PreviewTextInput(object sender, System.Windows.Input.TextCompositionEventArgs e)
{
// Just Ints
Regex regex = new Regex("[^0-9]+");
e.Handled = regex.IsMatch(e.Text);
}
那么像我描述的那样的浮点数格式化程序是什么样子的?
我对您的要求解读如下:
- 字符串前面可能有一个可选的“-”字符
- 在小数点分隔符之前,应该有一个“0”,或者任何不以“0”开头的数字。
- 在小数点分隔符之后,应该有一个“0”,或者任何不以“0”结尾的数字。
这直接转换为以下正则表达式:
@"^-?(0|[1-9]\d*)[,\.](0|\d*[1-9])$"
如果允许没有小数点分隔符的数字(问题对此不清楚),则从分隔符开始的部分将是可选的,即
@"^-?(0|[1-9]\d*)([,\.](0|\d*[1-9]))?$"
根据您的要求,以下模式似乎可行:
^-?(?!.*0$)(?!0\d)\d+(?:[,.]\d+)?$
见demo
^
- 开始字符串 ancor。-?
- 允许使用负值的可选连字符。(?!.*0)
- 否定前瞻以防止以0
. 结尾的字符串
(?!0\d)
- 否定前瞻以防止以0
和数字开头的字符串。\d+
- 任何数字至少出现一次。(?:
- 打开非捕获组。[,.]
- 逗号或点作为十进制分隔符。\d+
- 一个或多个数字。)?
- 关闭非捕获组并使其可选。
$
- 结束字符串锚点。
如果您想检查用户是否输入了有效的十进制数,.NET 为您提供了可读且简单的验证方法。只需使用 decimal.TryParse
本着“为工作使用正确的工具”的精神,您不应使用正则表达式进行此类验证。
就像这样使用它:
var parseOk = decimal.TryParse(textBlock.Text, out _); // here I used _ as parameter name, as it is not relevant
if(! parseOk)
{
// validation failed
}
为了控制小数分隔符的处理方式,您可以使用重载方法:
public static bool TryParse (string s, System.Globalization.NumberStyles style,
IFormatProvider provider, out decimal result);
此外,您还必须决定数字的存储方式(浮点数、十进制数或双精度数)。幸运的是,这些类型中的每一种都公开了两个静态方法:Parse
和 TryParse
- 我鼓励您阅读它们。