在C#中给出正则表达式,有没有办法生成这个正则表达式接受的单词?
例如,我们考虑一下:
[ab]c*b*
是否有一个可以自动生成枚举的函数,如:
a
b
ac
ab
bc
bb
acb
bcb
acc
bcc
...
显然,这个列表无限可能是你想要的词,生成器必须是智能的才能输出从最简单到最复杂的东西,而不是被困在无限循环中。 / p>
我认为这将是一个有用的工具,以验证正则表达式。通常,很容易看出正则表达式接受您计划接受的单词。通常要难以看到它会接受哪些其他词语。
编辑:这个问题不是关于如何做到的,而是:在C#中有什么我可以使用的吗?
答案 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图表既可用于识别单词,也可用于枚举所有可能的单词。我们通过非确定性地遍历图表来做到这一点。意思是,我们需要跟踪图中所有可能的路径。
从零开始,我们执行BFS,对于具有两个或更多输出边缘的每个节点,我们创建一个新的非确定性路径。每次打印时,BFS按以下顺序访问节点:
0, 1, 7, 2, 4, 8, 3, 5, 9, 6, 6, 10, 1, 1, 7, ...
对于每个访问过的节点,我们都有中间临时路径:
" e" symbol是表示空字符串""
的epsilon字母,在打印每个单词时应将其过滤掉。
通过在图表上执行BFS,我们将每个单词按照NFA再次识别单词所需的边数进行排序。由于图表包含一个循环,因此该过程永远不会完成。
每次非确定性路径到达结束节点10时,我们打印生成的字符串: