我正在尝试根据模式进行简单的字符串生成 我的想法是使用Regex进行简单的替换。 我从简单的方法开始:
private static string parseTemplate(string template)
{
return Regex.Replace(template, @"(\[d)((:)?([\d]+)?)\]", RandomDigit());
}
private static string RandomDigit()
{
Random r = new Random();
return r.Next(0, 9).ToString();
}
现在做的是将[d]
,[d:3]
等组替换为应该是随机数字的组。
不幸的是,每个组都被替换为相同的数字,例如,如果我放test [d][d][d:3]
我的方法将返回test 222
。
我想在每个地方获得不同的数字,例如test 361
。
我遇到的第二个问题是如何处理长度:
现在我必须为我想要的每个数字指定[d]
,但指定[d:3]
并获得相同的输出会更容易。
我知道有一个名为Fare的项目,但我想在没有此库的情况下执行此操作
现在我只搜索[d]
,但此方法是否正常可以添加其他组,例如:[s]
特殊字符或任何其他类型的图案都没有问题
EDIT1
有人建议我将Random更改为静态变量,如下所示:
private static string parseTemplate(string template)
{
return Regex.Replace(template, @"(\[d)((:)?([\d]+)?)\]", RandomDigit());
}
private static Random r = new Random();
private static string RandomDigit()
{
return r.Next(0, 9).ToString();
}
问题在于,当我这样调用我的代码时:
Console.WriteLine(parseTemplate("test [d:2][d:][d]"));
Console.WriteLine(parseTemplate("test [d:2][d:][d]"));
我得到像这样的输出
test 222
test 555
我想输出这样的(例如):
test 265
test 962
我认为问题出在Regex.Replace
上,只调用RandomDigit
一次。
答案 0 :(得分:3)
关于你的第一个问题:当你调用new Random()
时,每次调用函数时都会播放相同的值 - 初始化静态Random
成员变量一次然后返回r.Next(0,9).ToString();
在回答您的评论时,请尝试将MatchEvaluator与委托一起使用,如下所示(未经测试):
static string RandomReplacer(Match m)
{
var result = new StringBuilder();
foreach (char c in m.ToString())
result.Append(c == 'd' ? RandomDigit() : c);
return result.ToString()
}
private static string parseTemplate(string template)
{
return Regex.Replace(template, @"(\[d)((:)?([\d]+)?)\]", new MatchEvaluator(RandomReplacer));
}
然后,您可以扩展此方法以匹配[d:3]
,并相应地在您的MatchEvaluator中解析它,解决您的第二个问题。
答案 1 :(得分:1)
Assumnig [d:3]
表示“三个随机数字”,以下MatchEvaluator
使用长度(从第4组读取)生成随机数字字符串:
static string ReplaceSingleMatch(Match m)
{
int length;
if (!int.TryParse(m.Groups[1].Value, out length))
length = 1;
char[] chars = new char[length];
for (int i = 0; i < chars.Length; i++)
chars[i] = RandomDigit()[0];
return new string(chars);
}
然后您可以按如下方式调用它:
private static string parseTemplate(string template)
{
return Regex.Replace(template, @"\[d(?::(\d+))?\]", ReplaceSingleMatch);
}
您可能希望更改RandomDigit
以返回单个char
而不是字符串,或者取int
并返回多个字符。
答案 2 :(得分:1)
private static string GenerateMask(string mask)
{
StringBuilder output = new StringBuilder();
for (int i = 0; i < mask.Length; i++)
{
if (mask[i] == 'd' && mask[i - 1] != '\\')
{
int quantifier = 1;
if (mask[i + 1] == ':')
Int32.TryParse(mask[i + 2].ToString(), out quantifier);
output.Append(GetRandomDigit(quantifier));
i += 2;
}
else
{
if(mask[i] != '\\')
output.Append(mask[i]);
}
}
return output.ToString();
}
private static string GetRandomDigit(int length)
{
Random random = new Random();
StringBuilder output = new StringBuilder();
while (output.Length != length)
output.Append(random.Next(0, 9));
return output.ToString();
}
有一个自定义算法,我只是为了好玩而放在一起,这里是实现:
Console.WriteLine(GenerateMask(@"Hey Da\d, meet my new girlfrien\d she's d:2"));
//Output: Hey Dad, meet my new girlfriend she's 44