按照 Oli Charlesworth 所说,您可以构建 DFA 以使基数b
除以某个除数d
,其中 DFA 中的状态代表除法的其余部分。
对于您的情况(基数 2 - 二进制数,除数d
= 3 10):
请注意,上面的 DFA 接受空字符串作为可被 3 整除的“数字”。这可以通过在前面添加一个中间状态来轻松解决:
转换为理论正则表达式可以用正常的过程来完成。
当您获得 DFA 后,可以轻松地转换为支持递归正则表达式的风格中的实用正则表达式。在CodeGolf.SE的这个问题中显示了 (base b
= 10, d
= 7 10 ) 的情况。
让我在 Lowjacker 的答案中引用正则表达式,用 Ruby 正则表达式风格编写:
(?!$)(?>(|(?<B>4\g<A>|5\g<B>|6\g<C>|[07]\g<D>|[18]\g<E>|[29]\g<F>|3\g<G>))(|(?<C>[18]\g<A>|[29]\g<B>|3\g<C>|4\g<D>|5\g<E>|6\g<F>|[07]\g<G>))(|(?<D>5\g<A>|6\g<B>|[07]\g<C>|[18]\g<D>|[29]\g<E>|3\g<F>|4\g<G>))(|(?<E>[29]\g<A>|3\g<B>|4\g<C>|5\g<D>|6\g<E>|[07]\g<F>|[18]\g<G>))(|(?<F>6\g<A>|[07]\g<B>|[18]\g<C>|[29]\g<D>|3\g<E>|4\g<F>|5\g<G>))(|(?<G>3\g<A>|4\g<B>|5\g<C>|6\g<D>|[07]\g<E>|[18]\g<F>|[29]\g<G>)))(?<A>$|[07]\g<A>|[18]\g<B>|[29]\g<C>|3\g<D>|4\g<E>|5\g<F>|6\g<G>)
分解它,你可以看到它是如何构造的。原子分组(或非回溯组,或具有所有格行为的组)用于确保仅匹配空字符串替代项。(?DEFINE)
这是在 Perl中模拟的一个技巧。然后,当数字除以 7 时,组对应于 0 到 6 的余数A
。G
(?!$)
(?>
(|(?<B>4 \g<A>|5 \g<B>|6 \g<C>|[07]\g<D>|[18]\g<E>|[29]\g<F>|3 \g<G>))
(|(?<C>[18]\g<A>|[29]\g<B>|3 \g<C>|4 \g<D>|5 \g<E>|6 \g<F>|[07]\g<G>))
(|(?<D>5 \g<A>|6 \g<B>|[07]\g<C>|[18]\g<D>|[29]\g<E>|3 \g<F>|4 \g<G>))
(|(?<E>[29]\g<A>|3 \g<B>|4 \g<C>|5 \g<D>|6 \g<E>|[07]\g<F>|[18]\g<G>))
(|(?<F>6 \g<A>|[07]\g<B>|[18]\g<C>|[29]\g<D>|3 \g<E>|4 \g<F>|5 \g<G>))
(|(?<G>3 \g<A>|4 \g<B>|5 \g<C>|6 \g<D>|[07]\g<E>|[18]\g<F>|[29]\g<G>))
)
(?<A>$| [07]\g<A>|[18]\g<B>|[29]\g<C>|3 \g<D>|4 \g<E>|5 \g<F>|6 \g<G>)