正则表达式:语言生成器

时间:2012-03-02 15:07:19

标签: c# regex

在C#中给出正则表达式,有没有办法生成这个正则表达式接受的单词?

例如,我们考虑一下:

[ab]c*b*

是否有一个可以自动生成枚举的函数,如:

a
b
ac
ab
bc
bb
acb
bcb
acc
bcc
...

显然,这个列表无限可能是你想要的词,生成器必须是智能的才能输出从最简单到最复杂的东西,而不是被困在无限循环中。 / p>

我认为这将是一个有用的工具,以验证正则表达式。通常,很容易看出正则表达式接受您计划接受的单词。通常要难以看到它会接受哪些其他词语。

编辑:这个问题不是关于如何做到的,而是:在C#中有什么我可以使用的吗?

2 个答案:

答案 0 :(得分:1)

这甚至不是C#特定的问题;我认为你可以用任何真正的正则表达式做到这一点。

在我看来,你应该能够告诉任何正则表达式匹配的一代故事,这只是一个重写列表。在您的示例中,[ab]c*b*可以生成acccbbb;这是[ab]c*b* - > ac*b* - > acccb* - > acccbbb。对于每个运算符,我们可以想象枚举它重写的所有方式;那么这只是一个列举所有重写组合的问题,归结为枚举所有自然的N元组。

编辑:N-tuples of naturals是一个滑稽的比较。但你可以想象基本上在重写状态下执行广度优先遍历,输出所有运算符都被重写的每个字符串。

答案 1 :(得分:0)

我不知道如何在C#中做到这一点,但理论上是的,可以做到。

您需要将正则表达式转换为NFA或DFA图形,横向使用BFS跟踪当前路径,为每条边的路径添加新字符,并在完成节点时打印当前路径击中。根据手头的正则表达式,您的内存使用量很容易呈指数级增长。

例如,给定正则表达式(a|b)*abb,我们可以创建NFA图,如下所示:

NFA for <code>(a|b)*abb</code>

此NFA图表既可用于识别单词,也可用于枚举所有可能的单词。我们通过非确定性地遍历图表来做到这一点。意思是,我们需要跟踪图中所有可能的路径。

从零开始,我们执行BFS,对于具有两个或更多输出边缘的每个节点,我们创建一个新的非确定性路径。每次打印时,BFS按以下顺序访问节点:

0, 1, 7, 2, 4, 8, 3, 5, 9, 6, 6, 10, 1, 1, 7, ...

对于每个访问过的节点,我们都有中间临时路径:

  • 0,&#34;&#34;
  • 1,&#34; e&#34;
  • 7,&#34; e&#34;
  • 2,&#34; ee&#34;
  • 4,&#34; ee&#34;
  • 8,&#34; ea&#34;
  • 3,&#34; eea&#34;
  • 5,&#34; eeb&#34;
  • 9,&#34; eab&#34;
  • 6,&#34; eeae&#34;
  • 6,&#34; eebe&#34;
  • 10,&#34; eabb&#34;
  • 1,&#34; eeaee&#34;
  • 1,&#34; eebee&#34;

&#34; e&#34; symbol是表示空字符串""的epsilon字母,在打印每个单词时应将其过滤掉。

通过在图表上执行BFS,我们将每个单词按照NFA再次识别单词所需的边数进行排序。由于图表包含一个循环,因此该过程永远不会完成。

每次非确定性路径到达结束节点10时,我们打印生成的字符串:

  • &#34; ABB&#34;
  • &#34; AABB&#34;
  • &#34; BABB&#34;