如果值小于“nnnn”,则条件正则表达式替换

时间:2009-08-19 06:49:09

标签: .net regex

不确定这是否可以使用正则表达式替换命令,但我有一个现有的正则表达式替换,它将数字的最后两位数字转换为前缀为句号的最后两位数字。这是为了连接到一个系统,该系统通过货币值发送“2500”,其中这代表“25.00”美元。

我现有的正则表达式:(\d+)(\d{2})$
使用替换语法:$1.$2

现在我遇到了一个问题,如果一个值仅以例如“50”发送,这可能代表0.50并且我的正则表达式将失败,因为它在左边搜索1+数字,而两个数字正好在字符串的结尾。

我如何能够涵盖所有这些情况并让我的正则表达式替换为:

2500 = 25.00
500 = 5.00
50 = 0.50
5 = 0.05

再次感谢, 格雷厄姆

更新:对于那些问为什么这不能成为分界和字符串格式的工作是因为我必须避免自定义编程来实现这一点。理想情况下,它必须是数据库中定义的正则表达式“规则”以及其他正则表达式定义,因为它用于通用翻译系统。它将转换可能有多种格式类型的传入数据,例如,通常将字段从“101”转换为“101A”,但在此特定情况下,此数据类型需要添加值。

第二次更新:我一直在考虑这个,因为我被绑定到一个数据库,任何人都会看到比使用%wackyMoney%或db字段中定义的其他'token'更好的方法然后测试我们是否在代码中点击此标记以应用C#字符串格式并划分?

5 个答案:

答案 0 :(得分:3)

.Net正则表达式可以使用匹配评估程序将匹配转换为所需的匹配项:

String result = Regex.Replace(
   "test 1 test 20 test 300 test 4000 test 50000",
   @"\d+",
   (match => (Double.Parse(match.Value) / 100).ToString("0.00")));

结果是:

test 0.01 test 0.20 test 3.00 test 40.00 test 500.00

答案 1 :(得分:2)

正则表达式无法创建不存在的内容,因此您无法添加不存在的零。所以答案是你不应该使用正则表达式。

您最好的选择是使用(Double.Parse(value) / 100).ToString("0.00")或其他类似的内容。


由于您需要在数据库中定义的通用规则集,我认为这里的错误是您将数字规则与字符串规则混合在一起。您应该使数据库支持不同类型的规则。

我认为你应该有一个额外的列来指定值是以数字方式修改还是以字符串形式修改。如果它应该用数字修改,你可以让当前用于替换的列指定一个乘数或类似的。

如果你想更进一步,你可以有一个简单的公式评估器,可以采取类似:x / 100 + " USD"。已经有很多这些可用于.NET,并且自己制作一个简单的也不是很难。

答案 2 :(得分:2)

为什么你使用正则表达式?!使用单个正则表达式并不是一种简单的方法,但你可以用几个(一个用于3+数字的情况,一个用于2位数字的情况,一个用于对于1位数的情况)。但...

我不知道确切的C#语法,但有些内容如下:

sprintf('%0.2f', «var»/100.0)
只要您的数字足够小以至于您的浮点类型精确到优于0.01,

似乎完全符合您的要求。对于双打来说,那就是四分之一。

编辑1

由于你需要regexp,你可以使用三个(在这里使用Perl语法,但是......):

s/^(\d+)(\d{2})$/$1.$2/;   # you already have this
s/^(\d{2})$/0.$1/;         # obvious variant 1
s/^(\d{1}$/0.0$1/;         # obvious variant 2

其中只有一个匹配(变体1需要3个字符,变体2正好2个字符,变体3正好1个字符),因此如果可以附加多个正则表达式,则可以使用此字符。我可以将所有这些都集成到Perl中的一个正则表达式中,但我不知道你是否有完整的Perl正则表达式功能(我对此表示怀疑)。毕竟,Perl可以做到:

s/^(\d+)$/sprintf('%0.2f', $1/100.0)/e

但这是作弊。你的正则表达式引擎有类似的东西吗?或者你说这是一个数据库的东西;你可以使用SQL的CASE条件吗?

答案 3 :(得分:0)

您是否有理由不将字符串转换为数字,除以100,然后转换回具有适当格式的字符串?

答案 4 :(得分:0)

这可能无法准确回答op的问题,但它可以为您提供有关如何根据条件利用匹配参数的一些想法。

如果月份> 1,则以下方法将交换日期的日期和月份部分。 12.
例如:

string myStr = "14/3/2018";
string newStr = MDYToDMY(myStr);
Console.WriteLine(newStr); // prints "3/14/2018"

    static string MDYToDMY(string input)
    {
        try
        {
            return Regex.Replace(input,
                "\\b(?<month>\\d{1,2})/(?<day>\\d{1,2})/(?<year>\\d{2,4})\\b",
                (match => (int.Parse(match.Groups["month"].Value) > 12) 
                    ? $"{match.Groups["day"]}/{match.Groups["month"]}/{match.Groups["year"]}" 
                    : $"{match.Groups["month"]}/{match.Groups["day"]}/{match.Groups["year"]}"),
                RegexOptions.None,
                TimeSpan.FromMilliseconds(150));
        }
        catch (RegexMatchTimeoutException)
        {
            return input;
        }
    }