描述一个可以识别9的倍数的有限状态机很容易:跟踪数字总和(mod 9)并添加下一个接受的数字。这样的FSM只有9个状态,非常简单!通过FSM可识别性和常规语言之间的等效性,存在一个9的倍数的正则表达式。但是,任何此类正则表达式都可能……非常……长。与之类似,可能约为千兆字节。
在https://www.quaxio.com/triple/上有一个有效的示例,可用于3的倍数。在页面底部,作者提供了一种“手动优化”的解决方案,该解决方案比原始转换要短一些。 FSM到正则表达式。
挑战:
您必须制作一个正则表达式来检测9的倍数。由于这种正则表达式预计会很长,因此我要求您提供一个可以打印正则表达式的程序。(如果您真的想提供一个完整的正则表达式,也许将其放在其他位置并在此处链接!)
您必须能够告诉我们您程序输出的准确字符数-因此,只有在程序运行得足够快的情况下,才可以尝试尝试一定长度的所有正则表达式,直到找到有效的正则表达式,这是不可接受的运行它完成并给我们最终的正则表达式长度!
当然,点是用于具有最短的输出正则表达式,而不是基于程序长度。由于正则表达式是我要的“程序”,并且在这里方便地传输太长了,因此我仍在标记此代码高尔夫球。
规则:
- 输入将仅包含匹配的字符
[0-9]*
。 - 您的正则表达式应匹配 9的倍数,但不能匹配其他任何东西。并非完全由数字0-9组成且为无效输入的案例可以根据需要匹配或失败。
- 考虑到DFA易于识别的动机,所得的正则表达式实际上必须是更具理论性的术语中的正则表达式,也就是说,仅是封闭正则语言的运算符。确切地说,唯一允许的事情是:
- 文字,字符范围(
[ab]
,[a-f]
,[^k]
),Kleene星(*
),锚(^
和$
),通过括号分组,在交替(|
),可选术语(?
),一个或更多的术语(+
),向前看符号((?=)
),负向前看符号((?!)
), lookbehinds((?<=)
),负lookbehinds((?<!)
),条件(如在https://www.regular-expressions.info/conditional.html -(?(?=test)then|else)
),和有界长度的反向引用(见下文)。
- 文字,字符范围(
- 那些东西例子不是不允许的:
- 任意长度的后向引用,前向引用,递归,子例程,循环结构,可执行代码,任何'eval'变体或用于将字符串转换为算术值的内置结构。
- 可以显示具有有限长度绑定字符串的反向引用是可以接受的,因为它们可以以有限状态存储并且不会改变语言的规则性。例如,正则表达式
(..2.[3-5])4\1.\1
是可以接受的,因为捕获组上有绑定长度\1
。这是常规建筑。之类的构造(2*)0\1
是不可接受的,因为捕获的组无法以有限状态存储。 - 您的正则表达式可以随意接受或拒绝带有多余前导零的整数。但是,
"0"
必须接受该字符串。
2
相关的,不确定是否将其视为重复项
—
ASCII纯字符,
啊,嗯!我搜索了“正则表达式多个”,但没有“正则表达式可整”。我想那是非常相似的,是的。
—
亚历克斯·梅伯格
还没有人说,所以欢迎来到PPCG和有趣的第一个挑战!正如另一位用户所提到的那样,通常建议(但不是必需)在沙箱中发布挑战建议,以便他们可以在发布到主项目之前获得反馈。但是,这是一个经过深思熟虑的明确挑战,因此没有理由将其移至沙盒中。希望您喜欢我们的社区!
—
Caird coinheringaahing
小于200 kb的解决方案是可能的,因此它不会那么庞大
—
Ton Hospel
使用.NET扩展名的解决方案:
—
Neil
^(0|9|(?<c>1|(?<c>2|(?<c>3|(?<c>4|(?<c>5|(?<c>6|(?<c>7|(?<c>8))))))))((?<-c>){9})?)*$(?(c).)