我从记录中获得了大约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
的定义。此外,放置在令牌周围的数据将被忽略并保留在原位。
我的问题在于操纵字符串和最佳实践。有人告诉我,如果要动态创建正则表达式可能会很昂贵。作为CS专业,我有一种感觉,“正确”(无论多么复杂)的解决方案是为我的代币制作词法分析器/解析器。我没有在C#中编写词法分析器/解析器的经验,因此我不确定围绕它的最佳实践。我正在寻找有效且易于调整的系统的指导。
答案 0 :(得分: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);
答案 1 :(得分: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;