在 TextBox.Text 中退格后 Regex.IsMatch 不起作用

Posted

技术标签:

【中文标题】在 TextBox.Text 中退格后 Regex.IsMatch 不起作用【英文标题】:Regex.IsMatch not working after backspace in TextBox.Text 【发布时间】:2021-11-02 02:15:52 【问题描述】:

我有一个带有LostFocus 事件处理程序的TextBox,它调用一个将TextBox 中的数字字符串格式化为数字格式的方法。例如,123456,78 返回123 456,78。 如果我改为以123 45 开头,它会正确返回12 345,00

但是,如果我先输入123456,78,它正确返回123 456,78,然后用退格键删除TextBox中的最后四个字符,即我通过单击退格键四次删除6,78,不是在职的。它只是将 123 45 保留在 TextBox 中。 但是,如果我选择 TextBox 中的所有文本并粘贴 123 45,它会正确返回 12 345,00

当我一次单步调试时,我看到方法参数amountIn 正确存储了字符串123 45,无论是在我使用退格键还是选择和粘贴时。但是,Regex.IsMatch() 在我使用退格键时返回 false,在我选择和粘贴时返回 true。因此,我相信退格会在字符串中留下某种在调试时不可见但被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;
    

【问题讨论】:

您是否考虑过改用decimal.TryParse 之类的东西? 飞狗,我试过你的方法,效果也不错。一个巧妙的解决方案!谢谢 【参考方案1】:

瑞典的CultureInfo.NumberFormat.NumberGroupSeparator 是不间断的空格字符,char 0xA0 (160),而不是 char 0x20 (32),通常用于分隔的空格,例如单词。

你可以看到它写得更好:

var cultureSE = CultureInfo.GetCultureInfo("se-SE");
string hexChar = ((int)cultureSE.NumberFormat.NumberGroupSeparator[0]).ToString("X2");

hexChar 将是 "A0"

使用的正则表达式 ^[0-9 ,.]+$ 不考虑这一点,它只考虑 char 0x20。 您可以将其更改为仅 [0-9 ,.]+ 以忽略它,但您可能希望使用 \s 代替,它还将匹配所有 Unicode 空白字符,包括非中断空白字符,如 char 0xA0。 另见:Character classes in regular expressions

然后可以更改表达式:

if (Regex.IsMatch(amountIn, @"^[0-9\s,.]+$"))

     // Convert to a culture-specific number representation

【讨论】:

太棒了!谢谢!【参考方案2】:

不需要正则表达式:

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

【讨论】:

由于您正在解析用户输入(通常包括 胖手指 输入错误),请考虑使用 decimal.TryParse 而不是 .Parse 这很明显,但会更清楚))

以上是关于在 TextBox.Text 中退格后 Regex.IsMatch 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

无法在使用脚本放置逗号的文本区域中退格

SecureCRT远程连接Linux下的sqlplus中退格键不能使用之解决方法

android - 退格后搜索不会重新填充结果/列表

在vs中的MFC编程,文本输入编程,退格后会出现一道道竖线啥原因?在输入文字时,英语可以,中文显示不出

c#大于等于3小于等于99正则表达式怎么写? (Regex.IsMatch(textBox1.Text, "[3-9]1,"))

使用正则表达式验证IP地址