【问题标题】:Regex for decimals with maximum length具有最大长度的小数的正则表达式
【发布时间】:2016-04-25 12:34:03
【问题描述】:

我不确定这是否可以使用正则表达式。我会尝试使用正则表达式,但如果不可能,我会切换到双重验证。

我的数据库 (postgresql) 接受 decimal 为 15,6(最多 15 位,最多 6 位小数),所以如果我有 10 位整数,我可以有 5 位小数。小数点分隔符被忽略。

我目前有这个正则表达式(逗号是小数分隔符):

^\d{1,15}(\,\d{1,6})?$

它不验证总长度,只验证左边的数字。 但由于用户也可以输入点(千位分隔符),所以我有这个怪物:

^((\d+)|(\d{1,3}(\.\d{3})+)|(\d{1,3}(\.\d{3})(\,\d{3})+))((\,\d{4})|(\,\d{3})|(\,\d{2})|(\,\d{1})|(\,))?$

这个不接受超过 3 位小数。我可以编辑这个以接受 6 分,但我仍然无法验证总长度。

是否可以验证号码的总长度?忽略点和逗号。

正则表达式应该接受:

1234567890,123456

1.234.567.890,123456

当然还有其他中间值:

1.234,121,01...

【问题讨论】:

  • 你用什么语言来做这个?标记可能有助于获得更多关注。
  • 好吧,它是 c#。谢谢。
  • 你想做什么?小数是数字,而不是文本值。他们没有分隔符。如果您想验证一个值,您可以在 DTO 级别使用 UI 验证器和数据注释等
  • @PanagiotisKanavos 我正在尝试验证 TextBox 中的输入。
  • 虽然可以想出一个与您的情况相匹配的正则表达式,但它可能不是一个简单的。也许使用 Double.TryParse 和 NumberStyles 来解析输入并进行一些手动检查。如果TryParse 成功,您几乎可以做任何事情。例如,您可以 ToString 它并拆分小数点以检查字符串长度。它不像正则表达式那样单行,但更容易理解。

标签: c# regex


【解决方案1】:

我觉得你需要

^(?:\d{1,3}(?:\.\d{3}){0,4}|\d{1,15})(?:,\d{1,6})?$

regex demo

整数部分只允许 1 到 15 位数字(或 5 组 3 位数字块,用 . 数字分组符号分隔),并且可以选择后跟逗号和 1 到 6 位小数位。

  • ^ - 字符串开头
  • (?:\d{1,3}(?:\.\d{3}){0,4}|\d{1,15}) - 2 种选择:
    • \d{1,3}(?:\.\d{3}){0,4} - 1 到 3 位数字,后跟 0 到 4 个点序列 (\.) 和 3 位数字 (\d{3})
    • | - 或
    • \d{1,15} - 1 到 15 位数字
  • (?:,\d{1,6})? - 逗号的可选序列(1 或 0 次出现)后跟 1 到 6 位数字
  • $ - 字符串结束

【讨论】:

  • 总长度不能> 15,包括小数位数。所以这里有一个小改动:^(( your regex ){1,15})?$ 但我可能错了。
  • 我怀疑 ^(( your regex ){1,15})?$ 是否是您所需要的,它会匹配更多...但是,您对数据有更深入的了解,很高兴我能提供帮助。
  • 怎么能匹配得更多?
  • 我不知道你最后的正则表达式是什么意思。如果用另一对 () 将其括起来并设置 {1,15} 量词,它将匹配我的正则表达式匹配的 1 到 15 次。
  • 哦,那是个错误,我的意思是验证总长度。我忘记了。 :O
【解决方案2】:

只是将其作为替代方案扔掉。在我看来,在这种情况下你不应该使用正则表达式。为什么?因为真正匹配问题的正则表达式不容易理解。

对于这个问题存在更简单的解决方案。以这个为例:

var input = "1.234.567.890,123456";
var input2 = Regex.Replace(input, @"[^\d,]+", "");

var split = input2.Split(',');
var totalLength = split[0].Length + split[1].Length;

没什么特别的。但它确实有效,与迄今为止提供的其他解决方案不同。

但是不同的文化背景呢?不同的文化使用不同的千位分隔符。这就是像Double.TryParse 这样的东西可以进来的地方:

var input = "1.234.567.890,123456";

var style = NumberStyles.Number;
var culture = CultureInfo.CreateSpecificCulture("nl-NL");

double result;
if (double.TryParse(input, style, culture, out result))
{
    Console.WriteLine("It worked!");
}
else
{
    Console.WriteLine("Not valid");
}

上述方法有效,因为nl-NL 文化使用该格式。将其设置为en-US,它将失败。

两者都没有真正使用正则表达式来完成工作,但它们仍然可以产生所需的结果。

【讨论】:

  • 我正在使用类似的东西,使用正则表达式来验证千位和小数分隔符,并使用text.Replace(".", "").Replace(",", "") 来获取总长度。谢谢,我将停止在这种情况下使用正则表达式。
【解决方案3】:

试试这个:^[\d\.\,]{1,15}([\.\,]\d{0,6})?$

【讨论】:

  • 这将允许 123456789012345,123456。
  • 很好,它忽略了点和逗号,但它接受123456789011111,123456,忽略了长度限制。
  • @NickeManarin 你想做什么? .NET 具有验证器和数据注释,允许您验证十进制值,而无需将它们转换为文本,也不必处理负数、千位和小数分隔符
  • @PanagiotisKanavos 文本验证,小数位数的最大长度和总长度的验证,带和不带千位分隔符。
【解决方案4】:
^(\d{0,15})([\.\,]\d{0,6})?$
  • 第 1 组:
    最大长度 = 15 的任何数字
  • 第 2 组:
    最大长度为 2 的任意数字,前面为 ,.

【讨论】:

  • 抱歉,此答案未解决问题、重复或无法改进。
猜你喜欢
  • 1970-01-01
  • 2012-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-21
  • 1970-01-01
相关资源
最近更新 更多