为了提高自己的数学能力(总结归纳、逻辑推理、抽象),准备每天做1~3道有点挑战性的题目。那就先从正则表达式开始吧,网站是https://alf.nu/RegexGolf。感兴趣的同学也可以去玩玩。目标是匹配上下图左边的所有表达式,并且不能匹配右边的所有表达式(而且正则表达式越短越好)。
1. Warmup
这个题很简单,答案为foo。
2. Anchors
容易观察到左边的都是以ick结尾的(ick$)。那看看能不能减少正则表达式长度->左边都是以k结尾的(k$)。
3. It never ends
不能使用$,那能否有别的表示方式呢?如果知道\b(代表着单词的开头或结尾),就可以使用u\b了。
4. Ranges
观察规律,答案为[a-f]{4,6},那能否再进行简化呢?最佳答案为[a-f]{4}。
5. Backrefs
答案为(…).*\1
6. Abba
^(?!.*(.)(.)\2\1),其中?!表示的是后面不是,但是一定要添加括号。
7. A man, a plan
^(.)(.).*\2\1$,本质上是回文字符串,但是正则无法精确表达。所以观察下是否能够简化回文。
8. Prime
这个题目涉及到素数和合数的理解。什么是合数,合数本质上是可以表达成相同的若干份的。^(?!(.{2,})\1+$),如果理解不了答案的话,可以表达成偶数个x,然后再扩展即可。
9. Four
(.).\1.\1.\1,这样的写法是否可以优化呢?优化后的结果为(.)(.\1){3}
10. Order
^.{4,5}[^e]$,是否还能进行优化?,优化后结果为^.{5}[^e]?$,所以对于正确答案中字符串长度为[n,n+1],可考虑使用?。
11. Triples
完美的解答涉及到有限状态机等编译原理的内容,可参考https://www.jianshu.com/p/7fc0e079e212。暂时还理解不了,就用投机取巧的方法:^(14|31|32|36|39|40|44|71|74|81|87|90|95)|(50|00|003|60|09|12|015|70|06)$
12. Glob
分成三部分:
^(.*) .* \1\$|^(.*)\*(.*) .* \2.+\3$|(.*)\*(.*)\*(.*) .* \4.+\5.+\6,
这种是最完整的写法,我们可以进行化简,前两步无法化简,
最后一步可以简单化简,结果为
$^(.*) .+ \1$|^(.*)\*(.*) .+ \2.+\3$|^(.*)\*(.+)\*(.*) .+ .+\5.+$