【问题标题】:regex for multiple formats decimals and thousand separator多格式小数和千位分隔符的正则表达式
【发布时间】:2014-07-31 16:09:09
【问题描述】:

我需要正则表达式来验证一个可能包含千位分隔符的数字,该分隔符可能是三个不同字符之一(.,)或可能是 ,. 的小数。没有最大值或最小值,所以这不是问题。如果数字中没有小数,则应添加。一旦检测到,我就可以将生成的表达式处理成一套标准格式。

需要检测的示例值(左侧的值是要检测的值,右侧的值是我们将编码到的输出,但在此处显示是为了更好地了解我的需求):

11,111.11 => 11111.11

11'111.11 => 11111.11

11 111.11 => 11111.11

11.111,11 => 11111.11

11'111,11 => 11111.11

11 111,11 => 11111.11

11,111 => 11111.00

11'111 => 11111.00

11 111 => 11111.00

11.111 => 11111.00

对于输入值可能因不同标准格式(取决于最终用户)而不同的网站而言,这是必需的。在瑞士,所有这些可能的组合都可以使用。

我们将不胜感激。

【问题讨论】:

  • 11.11111,111在哪个逻辑中都表示11111.00?你如何解释11,111,111,111
  • 这是什么语言? Javascript?
  • 在瑞士,千位分隔符可以是.', 或空格。他们还使用. 作为千位分隔符,然后他们将使用, 作为小数点。但是,我将剥离所有千位分隔符并将所有小数转换为 .
  • 我希望我永远不会接触到实现此逻辑的应用程序。特别是如果它是银行应用程序。这太危险了。
  • @OnlineCop php 提交

标签: regex separator decimal-point


【解决方案1】:

您可以尝试下面的 sn-p,因为我不知道如何使用单个正则表达式来实现这一点。

$string = array("0,89", "11,111,111,111", "11,111.11", "11'111.11", "11 111.11", "11.111,11", "11'111,11", "11 111,11", "11,111", "11'111", "11 111", "11.111");
$pattern = "/^(\d{1,3}([,\s.']\d{3})*|\d+)([.,]\d+)?$/";
foreach($string as $price){
    preg_match($pattern, $price, $matches);
    echo $matches[0] , " -> " , preg_replace("/[,\s.']/", "", $matches[1]) , ((!empty($matches[3])) ? preg_replace("/[,\s.']/", ".", $matches[3]) : ".00") , "<br />";
}

输出:

0,89 -> 0.89
11,111,111,111 -> 11111111111.00
11,111.11 -> 11111.11
11'111.11 -> 11111.11
11 111.11 -> 11111.11
11.111,11 -> 11111.11
11'111,11 -> 11111.11
11 111,11 -> 11111.11
11,111 -> 11111.00
11'111 -> 11111.00
11 111 -> 11111.00
11.111 -> 11111.00

如您所见,在第一步中,上述模式将匹配任何(有效)价格格式并将其分为三组。在第二步中,组 (1) 将清除所有分隔符,而组 (3) 中的分隔符如果存在,将替换为点 (.)(如果需要,将添加零)

更多测试请查看demo

【讨论】:

    【解决方案2】:

    只是为了澄清(不是作为“答案”,而是因为 cmets 不允许此响应的长度),您打算遇到这些类型的输入吗?是否缺少任何场景?

    编辑: 分隔小数,添加一些“无效”情况。

    ### WITH DECIMALS ###
    
    # No separators, with decimals (using '.')
    1.00    10.00   100.00  1000.00 10000.00    100000.00   1000000.00  10000000.00 100000000.00
    
    # No separators, with decimals (using ',')
    1,00    10,00   100,00  1000,00 10000,00    100000,00   1000000,00  10000000,00 100000000,00
    
    # Thousand separators (using ','), with decimals (using '.')
    1,000.00    10,000.00   100,000.00  1,000,000.00    10,000,000.00   100,000,000.00
    
    # Thousand separators (using '.'), with decimals (using ',')
    1.000,00    10.000,00   100.000,00  1.000.000,00    10.000.000,00   100.000.000,00
    
    # Thousand separators (using ' '), with decimals (using ',')
    1 000,00    10 000,00   100 000,00  1 000 000,00    10 000 000,00   100 000 000,00
    
    # Thousand separators (using "'"), with decimals (using '.')
    1'000.00    10'000.00   100'000.00  1'000'000.00    10'000'000.00   100'000'000.00
    
    # Thousand separators (using "'"), with decimals (using ',')
    1'000,00    10'000,00   100'000,00  1'000'000,00    10'000'000,00   100'000'000,00
    
    
    ### WITHOUT DECIMALS ###
    
    # No separators, no decimals
    1   10  100 1000    10000   100000  1000000 10000000    100000000
    
    # Thousand separators (using ','), no decimals
    1,000   10,000  100,000 1,000,000   10,000,000  100,000,000
    
    # Thousand separators (using '.'), no decimals
    1.000   10.000  100.000 1.000.000   10.000.000  100.000.000
    
    # Thousand separators (using ' '), no decimals
    1 000   10 000  100 000 1 000 000   10 000 000  100 000 000
    
    # Thousand separators (using "'"), no decimals
    1'000   10'000  100'000 1'000'000   10'000'000  100'000'000
    
    
    ### INVALID, reusing separator and decimal indicator ###
    
    1,000,00 10,000,00 100,000,00 1,000,000,00 10,000,000,00 100,000,000,00
    1.000.00 10.000.00 100.000.00 1.000.000.00 10.000.000.00 100.000.000.00
    
    
    ### INVALID, non-numeric input or invalid separators ###
    
    11a111.11
    1-000 1-000.00 1-000,00 100!000.00 
    

    【讨论】:

    • 第二个问题很关键。 Is it missing any scenarios?
    • 这是一个格式良好的说明,并且没有任何遗漏的场景。
    • 澄清一下,这个数字不会用于银行业务甚至计算,只是为了验证,因为客户要求我们迎合不同用户的习惯。此外,如果缺少任何模式,它不会是那么大的交易,因为它将被视为无效而被拒绝,并且将要求用户输入一个新号码。因此,如果我们遗漏了任何场景,我们会在用户测试期间发现。
    • 例如,如果输入了11a111.11,我们会自动将其无效。 Alpha 输入,或不是0-9.,' 或空格的输入将无效。
    • 如果你可以把它分成两个步骤,第一个可以在每个数字的末尾添加小数:regex101.com/r/wH1yQ0/2。您可能需要将,00 替换为.00。然后,第二步将删除所有 [.,' ] 之前的字符 [.,]\d\d: regex101.com/r/wH1yQ0/4
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-30
    • 2021-12-23
    • 2017-09-06
    相关资源
    最近更新 更多