从C#中的正则表达式模式生成文本的所有排列

所以我有一个正则表达式模式,我想生成该模式允许的所有文本排列。

例:

var pattern = "^My (?:biological|real)? Name is Steve$"; var permutations = getStringPermutations(pattern); 

这将返回以下字符串列表:

我的名字是史蒂夫

我的真名是史蒂夫

我的生物学名字是史蒂夫

更新:显然正则表达式有无限数量的匹配,所以我只想生成可选的字符串文字,如(?:biological | real)? 从我上面的例子。 像(。)*这样的东西有太多的匹配,所以我不会生成它们。

如果您将自己限制在两端锚定的正则表达式子集中,并且只涉及文字文本,单字符通配符和交替,则匹配字符串应该很容易枚举。 我可能会将正则表达式重写为BNF语法,并使用它来生成匹配字符串的详尽列表。 对于你的例子:

  ->     -> "My "  -> "" | "real" | "biological"  -> " name is Steve" 

从RHS上仅包含终端符号的产品开始,并枚举LHS上的非终端可能采用的所有可能值。 然后按照RHS的非终结方式进行制作。 对于非终结符号的连接,形成由每个RHS非终结符表示的集合的笛卡尔积。 对于交替,采用每个选项表示的集合的并集。 继续,直到你已经完成了 ,然后你就完成了。

但是,一旦包含’*’或’+’运算符,就必须与无限数量的匹配字符串竞争。 如果你还想处理像后向引用这样的高级function……你可能正在寻找与停机问题同构的东西!

一种可能有点奇怪的方法是首先将可能的选择放入数组中,然后基于数组生成正则表达式,然后使用相同的数组生成排列。

这是我写的一个函数的草图,它采用字符串列表并返回所有排列可能性的列表:(从每个中取出字符)

 public static List Calculate(List strings) { List returnValue = new List(); int[] numbers = new int[strings.Count]; for (int x = 0; x < strings.Count; x++) { numbers[x] = 0; } while (true) { StringBuilder value = new StringBuilder(); for (int x = 0; x < strings.Count; x++) { value.Append(strings[x][numbers[x]]); //int absd = numbers[x]; } returnValue.Add(value.ToString()); numbers[0]++; for (int x = 0; x < strings.Count-1; x++) { if (numbers[x] == strings[x].Length) { numbers[x] = 0; numbers[x + 1] += 1; } } if (numbers[strings.Count-1] == strings[strings.Count-1].Length) break; } return returnValue; }