1

如果这篇文章是重复的,我深表歉意,但我已经进行了广泛的搜索,似乎找不到有效的解决方案。

我正在研究 C# 的正则表达式。以下是要匹配的条件:

  • 货币
  • 没有美元符号
  • 1000 分隔符的逗号
  • 十进制
  • 小数点后只有两位数
  • 负数的括号

几个例子:

  1,024.12
    500.00
 10,456.23
      2.89
 (8,456.15)
     (1.63)

这是我正在使用的当前模式:

^\(?\d+\,?\d+[.]{1}\d{2}\)?

我认为这种模式可以解决问题,但是,在与此模式匹配的同一行上有一个由数字和句点构成的字符串。例子:

123.1234.12345.123456789.12345.123 

我知道这是非常基本的东西,但我很难让它只匹配货币部分而不是上面的字符串。

感谢您提供的任何建议

4

6 回答 6

5

您当前的表达式与列表中的第四个2.89和第六个示例不匹配(1.63)

相反,您可以使用以下表达式:

^(\()?[0-9]+(?>,[0-9]{3})*(?>\.[0-9]{2})?(?(1)\))$

这个表达式匹配 start-of-line ^,然后它尝试匹配一个可选的括号来匹配(负数,括号被捕获在一个组中,原因很快就会被清除。

现在它尝试匹配一个或多个数字[0-9]+,这应该涵盖所有整数,如234,5652等。

然后它查找可能的逗号(千位分隔符) ,后跟 3 位(?>,[0-9]{3})*重复零次或多次的数字,这包括包含千位分隔符的数字。

然后它试图找到一个小数点,.后跟正好 2 位数字(?>\.[0-9]{2})?,这当然是可选的,这包括十进制数字。

之后,表达式使用(?(1)\)) - 条件构造(?(id/name)yes-pattern|no-pattern)-因此,如果我们实际上匹配了一个左括号,那么我们应该匹配一个右括号,这可以防止表达式匹配不正确的负数,例如(2.4没有右括号。

最后是字符串的结尾,$以防止部分匹配,例如您的上一个示例。

正则表达式 101 演示

于 2013-08-30T14:23:34.013 回答
3

尝试添加$到你的正则表达式的末尾,所以你会得到

^\(?\d+\,?\d+[.]{1}\d{2}\)?$

这样,您至少将仅匹配.您提到的字符串之后恰好有 2 位数字的数字,不再匹配。

于 2013-08-30T13:57:12.593 回答
3
\(?\b[0-9]{1,3}(?:,?[0-9]{3})*\.[0-9]{2}\b\)?

将鼠标悬停在此处的表达式上以获得解释。

于 2013-08-30T14:08:53.753 回答
1

我认为这对您来说是一个很好的解决方案:

^\(?(0|[1-9][0-9]{0,2}(?:(,[0-9]{3})*|[0-9]*))\.[0-9]{2}\)?$

这将防止没有多大意义的数字,例如004,2.42

在此处输入图像描述

于 2013-08-30T14:53:44.403 回答
1

如果目标只是解析小数,则使用正确设置的NumberStyles的decimal.Parsedecimal.TryParse将满足您的需求。

const NumberStyles numberStyles = NumberStyles.AllowParentheses
                                    | NumberStyles.AllowThousands
                                    | NumberStyles.AllowDecimalPoint;
decimal parsed;
var successful = decimal.TryParse(s, numberStyles, CultureInfo.CurrentCulture, out parsed);

完整测试:

var values = new[]
    {
        "1,024.12",
        "500.00", 
        "10,456.23", 
        "2.89", 
        "(8,456.15)", 
        "(1.63)", 
        "123.1234.12345.123456789.12345.123"
    };

const NumberStyles numberStyles = NumberStyles.AllowParentheses
                                    | NumberStyles.AllowThousands
                                    | NumberStyles.AllowDecimalPoint;
var culture = CultureInfo.CurrentCulture;

foreach (var s in values)
{
    decimal parsed;
    var successful = decimal.TryParse(s, numberStyles, culture, out parsed);

    Console.WriteLine("Successful? {0}; Parsed = {1}", 
        successful, 
        successful ? parsed.ToString() : "?");
}

输出:

成功的?真的; 已解析 = 1024.12
成功的?真的; 已解析 = 500.00
成功的?真的; 已解析 = 10456.23
成功的?真的; 已解析 = 2.89
成功的?真的; 已解析 = -8456.15
成功的?真的; 已解析 = -1.63
成功的?错误的; 解析 = ?
于 2013-08-30T15:46:42.903 回答
0

你应该试试

^\(?\d+\,?\d+[.]{1}\d{2}\)?\\> 

或者

^\(?\d+\,?\d+[.]{1}\d{2}\)?\b

所以它在部分命中时不匹配。

于 2013-08-30T14:00:32.543 回答