Regex.IsMatch 在 TextBox.Text 中退格后无法正常工作
Regex.IsMatch not working after backspace in TextBox.Text
我有一个带有 LostFocus
事件处理程序的 TextBox,该事件处理程序调用一种方法,将 TextBox 中的数字字符串格式化为数字格式。例如,123456,78
returns 123 456,78
.
如果我改为从 123 45
开始,它会正确 returns 12 345,00
.
但是,如果我先输入 123456,78
,并且它正确 returns 123 456,78
,然后用退格键删除 TextBox 中的最后四个字符,即我删除 6,78
通过单击退格四次,它不起作用。它只是在 TextBox 中保留 123 45
。
但是,如果我 select TextBox 中的所有文本并正确粘贴 123 45
它 returns 12 345,00
。
当我通过一次单步执行调试时,我看到方法参数 amountIn
正确地存储了字符串 123 45
,无论是在我使用退格键还是在我 select 并粘贴。但是,Regex.IsMatch()
returns false
当我使用退格键时, true
当我 select 并粘贴时。因此,我相信退格键会在字符串中留下某种伪像,这种伪像在调试时是不可见的,但可以被 IsMatch()
方法识别。这是我的方法:
private void txtAmount_LostFocus(object sender, EventArgs e)
{
txtAmount.Text = ReformatAmount(txtAmount.Text);
}
public static string ReformatAmount(string amountIn)
{
string amountOut;
if (Regex.IsMatch(amountIn, @"^[0-9 ,.]+$"))
{
amountOut = Regex.Replace(amountIn, "[. ]", "");
amountOut = Convert.ToDecimal(amountOut).ToString("N");
return amountOut;
}
else
{
amountOut = amountIn;
return amountOut;
}
}
瑞典的CultureInfo.NumberFormat.NumberGroupSeparator是不间断的space字符,char0xA0
(160),不是char0x20
(32),白色的space 通常用于分隔,例如单词。
你写的更好看:
var cultureSE = CultureInfo.GetCultureInfo("se-SE");
string hexChar = ((int)cultureSE.NumberFormat.NumberGroupSeparator[0]).ToString("X2");
hexChar
将是 "A0"
。
正在使用的正则表达式,^[0-9 ,.]+$
没有考虑到这一点,它只考虑字符 0x20
.
您可以将其更改为 [0-9 ,.]+
以忽略它,但您可能想改用 \s
,它还将匹配所有 Unicode white-space 字符,包括不间断的 white-space 个字符,如 char 0xA0
.
另见:Character classes in regular expressions
表达式可以更改为:
if (Regex.IsMatch(amountIn, @"^[0-9\s,.]+$"))
{
// Convert to a culture-specific number representation
}
不需要正则表达式:
string[] nums = new[]
{
"123456,78",
"123 456,78",
"6,78",
"123 45"
};
foreach (var num in nums)
{
if (Decimal.TryParse(num, NumberStyles.Any, null, out decimal result))
{
// Number successfully parsed:
Console.WriteLine($"{result:N2}");
}
else
{
// Parsing error here
Console.WriteLine($"Could not parse: '{num}'");
}
}
输出:
123 456,78
123 456,78
6,78
12 345,00
我有一个带有 LostFocus
事件处理程序的 TextBox,该事件处理程序调用一种方法,将 TextBox 中的数字字符串格式化为数字格式。例如,123456,78
returns 123 456,78
.
如果我改为从 123 45
开始,它会正确 returns 12 345,00
.
但是,如果我先输入 123456,78
,并且它正确 returns 123 456,78
,然后用退格键删除 TextBox 中的最后四个字符,即我删除 6,78
通过单击退格四次,它不起作用。它只是在 TextBox 中保留 123 45
。
但是,如果我 select TextBox 中的所有文本并正确粘贴 123 45
它 returns 12 345,00
。
当我通过一次单步执行调试时,我看到方法参数 amountIn
正确地存储了字符串 123 45
,无论是在我使用退格键还是在我 select 并粘贴。但是,Regex.IsMatch()
returns false
当我使用退格键时, true
当我 select 并粘贴时。因此,我相信退格键会在字符串中留下某种伪像,这种伪像在调试时是不可见的,但可以被 IsMatch()
方法识别。这是我的方法:
private void txtAmount_LostFocus(object sender, EventArgs e)
{
txtAmount.Text = ReformatAmount(txtAmount.Text);
}
public static string ReformatAmount(string amountIn)
{
string amountOut;
if (Regex.IsMatch(amountIn, @"^[0-9 ,.]+$"))
{
amountOut = Regex.Replace(amountIn, "[. ]", "");
amountOut = Convert.ToDecimal(amountOut).ToString("N");
return amountOut;
}
else
{
amountOut = amountIn;
return amountOut;
}
}
瑞典的CultureInfo.NumberFormat.NumberGroupSeparator是不间断的space字符,char0xA0
(160),不是char0x20
(32),白色的space 通常用于分隔,例如单词。
你写的更好看:
var cultureSE = CultureInfo.GetCultureInfo("se-SE");
string hexChar = ((int)cultureSE.NumberFormat.NumberGroupSeparator[0]).ToString("X2");
hexChar
将是 "A0"
。
正在使用的正则表达式,^[0-9 ,.]+$
没有考虑到这一点,它只考虑字符 0x20
.
您可以将其更改为 [0-9 ,.]+
以忽略它,但您可能想改用 \s
,它还将匹配所有 Unicode white-space 字符,包括不间断的 white-space 个字符,如 char 0xA0
.
另见:Character classes in regular expressions
表达式可以更改为:
if (Regex.IsMatch(amountIn, @"^[0-9\s,.]+$"))
{
// Convert to a culture-specific number representation
}
不需要正则表达式:
string[] nums = new[]
{
"123456,78",
"123 456,78",
"6,78",
"123 45"
};
foreach (var num in nums)
{
if (Decimal.TryParse(num, NumberStyles.Any, null, out decimal result))
{
// Number successfully parsed:
Console.WriteLine($"{result:N2}");
}
else
{
// Parsing error here
Console.WriteLine($"Could not parse: '{num}'");
}
}
输出:
123 456,78
123 456,78
6,78
12 345,00