0

我有大约 10 条记录中的数据,我希望能够定义返回此数据的字符串的布局,并可以选择保留一些数据。我的想法是使用枚举为我的标记/字段提供整数值,然后使用类似{0}{1}{2}{3} 或复杂的格式{4} - {3}{1} [{8}]。标记的含义与我的数据库中的字段有关。例如,我有这个与付款相关的代币的枚举。

AccountMask = 0,
AccountLast4 = 1,
AccountFirstDigit = 2,
AccountFirstLetter = 3,
ItemNumber = 4,
Amount = 5

帐户掩码是一个类似 VXXXXX1234 的字符串,其中 V 代表签证,1234 是卡的最后 4 位数字。有时客户想要 V,有时他们想要第一位数字(将卡片类型转换为第一位数字很容易)。

我的目标是创建可重用的东西,以使用格式字符串中的标记生成字符串,然后使用与标记内的数字相关联的数据对数据进行就地替换。

因此,例如,如果我想定义格式,则使用上面的掩码和我的枚举9{2}{1}{4:[0:0000000000]}

如果项目编号是 678934

然后将转换为 9412340000678934 ,其中令牌 4 的内部部分成为String.Format该值的 a 的定义。此外,放置在令牌周围的数据将被忽略并保留在适当的位置。

我的问题涉及字符串的操作和最佳实践。有人告诉我,如果您要即时创建正则表达式,它们的成本可能会很高。作为一名 CS 专业的学生,​​我觉得“正确”(无论多么复杂)的解决方案是为我的令牌制作一个词法分析器/解析器。我没有用 C# 编写词法分析器/解析器的经验,所以我不确定围绕它的最佳实践。我正在这里寻找有关高效且易于调整的系统的指导。

4

2 回答 2

0

看到这个问题,我立马觉得解决方法很简单;存储您希望使用的掩码,以及您希望包含的各种数据字段的常量值,并将掩码传递给对 String.Format() 的常量调用:

const string CreditCardWithFirstLetterMask = "{3}XXXXXXXXXXX{1}";
const string CreditCardWithFirstDigitMask = "{2}XXXXXXXXXXX{1}";

...

var formattedString = String.Format(CreditCardWithFirstDigitMask, 
   record.AccountMask,
   record.AccountLast4,
   record.AccountFirstDigit,
   record.AccountFirstLetter,
   record.ItemNumber,
   record.Amount); 
于 2011-05-06T20:40:35.243 回答
0

我最终将正则表达式作为静态对象放入类中,然后循环匹配以执行替换并构建我的令牌。

var token = request.TokenFormat;

var matches = tokenExpression.Matches(request.TokenFormat);

foreach (Match match in matches)
{
    var value = match.Value;
    var tokenCode = (Token)Convert.ToInt32(value.Substring(1, (value.Contains(":") ? value.IndexOf(":") : value.IndexOf("}")) - 1));

    object data = null;

    switch (tokenCode)
    {
        case Token.AccountMask:
            data = accountMask;
            break;
        case Token.AccountLast4:
            data = accountMask.Substring(accountMask.Length - 4);
            break;
        case Token.AccountFirstDigit:
            string firstLetter = accountMask.Substring(0, 1);

            switch (firstLetter.ToUpper())
            {
                case "A":
                    data = 3;
                    break;
                case "V":
                    data = 4;
                    break;
                case "M":
                    data = 5;
                    break;
                case "D":
                    data = 6;
                    break;
            }

            break;
        case Token.AccountFirstLetter:
            data = accountMask.Substring(0, 1);
            break;
        case Token.ItemNumber:
            if(item != null)
                data = item.PaymentId;
            break;
        case Token.Amount:
            if (item != null)
                data = item.Amount;
            break;
        case Token.PaymentMethodId:
            if (paymentMethod != null)
                data = paymentMethod.PaymentMethodId;
            break;
    }

    if (formatExpression.IsMatch(value))
    {
        Match formatMatch = formatExpression.Match(value);
        string format = formatMatch.Value.Replace("[", "{").Replace("]", "}");

        token = token.Replace(value, String.Format(format, data));
    }
    else
    {
        token = token.Replace(value, String.Format("{0}", data));
    }
}

return token;
于 2011-05-19T14:55:31.083 回答