【问题标题】:Regex.IsMatch not working after backspace in TextBox.Text在 TextBox.Text 中退格后 Regex.IsMatch 不起作用
【发布时间】: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 之类的东西?
  • 飞狗,我试过你的方法,效果也不错。一个巧妙的解决方案!谢谢

标签: c# regex winforms


【解决方案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
  • 这很明显,但会更清楚))
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-05
  • 2011-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多