【问题标题】:Generate all Permutations of text from a regex pattern in C#从 C# 中的正则表达式模式生成文本的所有排列
【发布时间】:2009-10-07 23:53:00
【问题描述】:

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

例子:

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

这将返回下面的字符串列表:

我叫史蒂夫

我的真名是史蒂夫

我的生名是史蒂夫

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

【问题讨论】:

  • 所以它必须以My 开头,对吗?你不想捕捉像 Steve is my real name 这样的排列吗?

标签: c# .net regex string permutation


【解决方案1】:

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

<lang>   -> <begin> <middle> <end>
<begin>  -> "My "
<middle> -> "" | "real" | "biological"
<end>    -> " name is Steve"

从 RHS 上只有终端符号的产生式开始,然后枚举 LHS 上的非终结符可以取的所有可能值。然后工作 在 RHS 上使用非终结符进行制作。对于非终结符号的连接,形成由每个 RHS 非终结符号表示的集合的笛卡尔积。 对于交替,取每个选项所代表的集合的并集。继续 直到你一直努力到&lt;lang&gt;,然后你就完成了。

然而,一旦你包含了 '*' 或 '+' 操作符,你就不得不面对无穷大 匹配字符串的数量。如果您还想处理诸如反向引用之类的高级功能……您可能正在朝着同构的方向发展 到停机问题!

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

      public static List<string> Calculate(List<string> strings) {
                  List<string> returnValue = new List<string>();
                  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;
              }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-12-07
        • 1970-01-01
        • 2013-01-25
        • 1970-01-01
        • 2013-04-03
        • 2017-08-26
        • 1970-01-01
        相关资源
        最近更新 更多