2

我正在尝试基于模式进行简单的字符串生成。
我的想法是使用正则表达式进行简单的替换。我从简单的方法开始:

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]对于特殊字符或任何其他类型的模式。

编辑1

正如建议的那样,我将 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一次。

4

3 回答 3

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 中解析它,从而解决您的第二个问题。

于 2013-01-18T10:05:45.287 回答
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并返回多个字符。

于 2013-01-18T10:31:03.187 回答
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
于 2013-01-18T10:48:39.540 回答