正则大挑战

正则大挑战

最近发现的一个网站,关于正则的练习网站::链接,大概16题,从Easy到Hard,覆盖的面很广,有评分,也有很多大佬追求极致评分,页面大概长下面这样,让我们现在开始吧。

因为网站改版,现在已经不显示分数了,大致的评分机制如下:

Points = (需求列表匹配数 * 10) - (不允许列表匹配数 * 10) - 表达式字符数

例如:foo的字符数是3,需求列表匹配数=42,不允许列表匹配数=21,代入上面的公式:得到的分数是 207 207 207

在这里插入图片描述

下面的部分是Classic部分

1.Warmup

Type a regex in the box.

在这里插入图片描述

  • 仔细观察,左侧的字符都出现了foo这字符,右侧则没有,因此直接填入foo可以解,得分为 207 207 207

2.Anchors

You are deducted one point per character you use, and ten if you match something you shouldn’t.

在这里插入图片描述

  • 左侧的每个字符都是以ick结尾的,使用ick$,得分 206 206 206分,如果还想要精简一下的话,k$也可以做到匹配,得分能到 208 208 208

紧接着,根据上一题的做法,给了下面这道题,但是不允许有$

在这里插入图片描述

  • 考虑使用\b这个匹配,\b 断言此位置为单词边界:(^\w|\w$|\W\w|\w\W),u\b可以解本题,得分 207 207 207

3.Ranges

The test vectors were generated by grepping /usr/dict/words. Can you tell?

在这里插入图片描述

  • 考察的是字母的范围,观察下来,左侧的字母都是a-f之间的,右侧不需要匹配的,则超出了这个范围,^[a-f]*$可以解,要求a-f的字符出现了0次以上,得分 202 202 202

4.Backrefs

This doesn’t really work as a tutorial. Not really clear what you’re supposed to do here.

在这里插入图片描述

  • 观察下来是xxx......xxx这样的形式,如allochirally,all在前面出现过一次,在后面又出现了一次,这种结构很容易使用反向引用解决,(...).*\1可以解决,得分 201 201 201分,其中\1匹配与捕获组1st最近匹配的相同的文本,也就是前面的那个括号

5.Abba

Let’s pretend this one is not a rehash of the last one.

在这里插入图片描述

  • 这一题要求的是不能匹配形如abba这样结构的字符,如右侧的anallagmatic这个单词,alla便是这种结构,需要把这种结构的字符全部排除掉

  • 使用负向零宽先行断言,可以筛选出左侧匹配上的,(?!(.)(.)\2\1),但是右侧的不能筛选出来,而且需要排除掉这种串****xoox****,只需要在前后补字符并把这段能匹配上的字符全部排除掉,^(?!.*(.)(.)\2\1.*)为最终解,这个字符是19个,总的是43个单词,扣除右边不要的22个单词,得分是210-19= 191 191 191

  • 在本题中,去掉最后的字符匹配也能通过,^(?!.*(.)(.)\2\1),得分来到 193 193 193

  • 还看到多大神的一种解法^(?!.*(.)\1)相当于强制筛选abba中间的结构,而不管前后的a,然而输入进去后,发现左侧有两个应该要匹配的字符匹配不上,这时候观察了下这个两个字符,都有ef两个相连的字符^(?!.*(.)\1)|ef可以解本题,得分来到 195 195 195

在这里插入图片描述

6.A man, a plan

You’re allowed to cheat a little. Even in hard mode, words will be no longer than 13 characters.

在这里插入图片描述

  • 本题是要找这种回文结构,如deedeed,civic,也就是常说的偶回文,奇回文,写出(.)(.).?\2\1后发现,右侧有一个字符没有被排除掉,观察左侧的字符,可以往后再多多加一个字符强制提前结束,写出这样的正则:(.)(.).?\2\1.?$,得分为 175 175 175

在这里插入图片描述

  • 但是本题题干部分给出了「cheat」的字眼,那我们就不客气了,精简到只反向引用一个字符,写出^(.).*\1$,但是如下图,右侧有一个单词没有被排除掉,采用「cheat」的方式,排除掉这个单词^(.)[^p].*\1$,得分来到 177 177 177

在这里插入图片描述

7.Prime

在这里插入图片描述

  • 题目要求筛选出长度是Prime也就是诸如2、3、5、7、11、13、17等这样的质数,的字符串,字符都是x组成的,一开始我看出了要判断括号的里的数字,其实是题面省略了x的个数,比如说xx...(17)..xx表示这一行x出现了17次,也就是质数,右侧的是非质数
  • 做法也很巧妙,主体思想是要筛掉右侧这种非质数,也就是诸如4、6、8、9、10、12、14、15、16等这样的数,了解埃筛(埃拉托斯特尼筛法)的话,这一题就很容易解答,首先发现2的倍数诸如4、6、8、10、12等这样的数不是质数、3的倍速6、9、12、15、18等这样的不是质数,同理对于5,7等数的倍数也不是质数,只需要使用反向引用可以达到翻倍的效果
  • (..+)+表示出现一次或者无数次,也就是说,某个字符出现2、3、4、5等次数,(..+)\1+,使用反向引用对前面匹配到的捕获组进行重复,+表示至少1次,通过这样的方式,保留了作为2、3、4、5这样的基本数,筛选出了2的倍数,3的倍数、4的倍数、5的倍数,加一个否定环视?!(..+)\1+,就能匹配到右边,而左边没匹配

在这里插入图片描述

  • 接着,提供一个反选,可以匹配到左边,晒出掉右边^(?!(..+)\1+$),KaTeX parse error: Undefined control sequence: \1 at position 41: …是可以的:`^(?!(xx+)\̲1̲+)`

在这里插入图片描述

8.Four

You can get an extra point by ignoring the name of this level.

请添加图片描述

  • 需要匹配这种x*x*x*x*结构,只需要反向引用第一个字符,整体3次即可,(.)(.\1){3},得分 199 199 199

在这里插入图片描述

9.Order

Cheat

  • 这一题题面已经给了可以「cheat」,看了下大佬的解,我不说话了:^.{5}[^e]?$,左边的字符都是5个,右边的字符都含有e这个字符,排除掉

在这里插入图片描述

10.Triples

Multiples of 7 are left as an exercise for the reader.

  • 这一题之前的文章详细介绍过怎么使用自动状态机构造符合3的倍数的正则:正则表达式如何匹配3的倍数?

  • 看了下牛人给出的答案,没什么营养,大体就是面向测试写正则:00($|3|6|9|12|15)|4.2|.1.+4|55|.17,这种方式应该是一种作弊手段,且不太可能被推广,7的倍数也可以使用上面链接讲到的方式去完成

在这里插入图片描述

11.Glob

在这里插入图片描述

  • 题意是想匹配xxx mathchs yyy这样的结构,可能xxx中有*,需要替换掉对应的字符,位置顺序必须一致,看了眼答案:ai|c$|^p|[bcnrw][bnopr],是观察出来的结果

12.Balance

This one is also impossible, but there’s a finite number of test cases.

在这里插入图片描述

  • 题意是要筛选出正确的括号对,^(<(..(?!<.>$))*>)*$ ,这里面用到了循环捕获组,只捕获最后一次匹配。在循环捕获组外层加一个括号以获取所有结果,或使用非捕获组如果您对捕获数据不感兴趣的话,这其中也使用了否定型顺序环视(?!<.>$),上面的结果不足以通过所有的case,最后补了一个.{37},排除掉了例外的情况,^(<(..(?!<.>$))*>)*$|.{37}是最终的答案

  • 括号配对,对于正则是一个非常大的难题,正则文法的定义先天就不是递归的。现在用的加强的正则表达式,尽管加入了反向引用、计数、前瞻后瞻等高级功能,只是在引擎层面新增了功能。

13.Powers

在这里插入图片描述

  • 这题和第7题Prime很像,想要的匹配的是1、2、4、8、32、64、128等这样2的幂的数量的字符串,3、5、7等这种不应该出现,这些长度的字符串有个特点,可以表示成2n+1,可以写出^(.(..)+)$这种形式的,可以筛选掉部分,但是401、1025这种长度的还是没有筛选掉,对这些不符合的数做因式分解,28=7*2*2, 48=3*2*2*2*2, 160=5*2*2*2*2*2, 600=75*2*2*2,也就是说都是(2n+1)*pow(2, m)

在这里插入图片描述

  • 也就是说,加一个反向引用可以达到倍数的效果,再把这些结构的字符长度的全部筛选掉,答案是:^(?!^(.(..)+)\1*$)

在这里插入图片描述

14.Long count

在这里插入图片描述

  • 又一个反向引用的例子,((.+)0\2+1){8},这段是观察后的结果,大体意思是把x0x1这种结构重复8次,当然\2+匹配的到的(.+)可以是0次

15.Alphabetical

To save typing the input will only use the characters a/e/n/r/s/t, even in hard mode.

在这里插入图片描述

  • 看了下答案.r.{32}r|a.{10}te|n.n..,三段的正则,应该是根据目标集找单词的规律的,好吧,这题我没看懂~

16.Powers 2

Or 3

在这里插入图片描述

  • 想要筛选掉不是3的幂的数,也就是筛选出1 、3、9、27、81这种、筛选掉2、4、5、6、7、8这种不是3的幂的数,和13题Powers类似,需要考虑筛选掉3n+1,3n+2的倍数,因为所有数mod3只有只有三种数0、1、2排除掉后两种
  • ^(?!((xxx)+x|xx)\1*$),里面括号可以筛选出3n+1,3n+2这样的数,最后反选掉

在这里插入图片描述

下面的部分是Teukon部分

17.Subtraction

  • 题目要求筛选出正确的等式

在这里插入图片描述

  • ^(.+)(.+) - \1 = \2$很好理解,第一部分的字符拆成两个部分,分别给到第一个反向引用和第二个反向引用

18.Typist

With apologies to Dr. Dvorak.

  • 找字符的规律:^[adresbtcfxzgvw]+$

在这里插入图片描述

19.Addition

Beauty in symmetry.

在这里插入图片描述

  • 和17题Subtraction类似,处理方式是将 = 号左右两边的+号当成一个组的字符来看,^(.*)(.*)(.*) = \3\2\1$ ,左边当成一个整体来看,反选掉不符合等式的结果

20.Anyway

Old MacDonald had a farm…

在这里插入图片描述

  • 大神的写法:^[aeiouy]?(.[aeiouy])+[^aeiou]?$

21.Tic-tac-toe

Don’t forget the horizontals.

在这里插入图片描述

  • 找的字符串的规律:XXX|OOO|([OX])...\1...\1|X..X..X|X....X....X,能筛选出来

总结

  • 后面还有题目,我没写完,有机会再发第二期吧~

Reference

  • https://gist.github.com/jonathanmorley/8058871

延伸阅读

个人主页

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值