挑战正则表达式

正则表达式是写爬虫的必备技能,在论坛发现了一个神奇的网站,据说“只要把这16个题做完,你就可以精通正则”,立贴挑战。

目前战绩:2803


Warmup

Type a regex in the box. You get ten points per match (or lose ten, if you match something you shouldn't); each character costs one point.

一眼就看到一大屏幕的 ***foo*** ,果断填入 foo,拿了 207

Anchors

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

也属于简单题,容易发现最后一个单词是 k,所以用个终止符 k$,208 分到手

It never ends

$ not allowed

嘛,不能用 $,没事直接 u\b

Ranges

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

发现需要匹配的字符都只有 abcdef 六种字符集,结合边界和集合可以写出 ^[a-f]+$,202 分

Backrefs

Perfect! Hit Enter to try the next level (or see if you can make it shorter for more points)

大概是要匹配含有 **abc**abc** 这种结构,用反向引用就可以解决,(.{3}).*\1,其实中间的 {3} 依情况而言可以写成 (...).*\1,分数从 200 升到 201

Abba

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

标题已经提示了,需要匹配的部分为含有长度为四的回文子串的字符串,依旧使用老套路,两个反向引用,(.)(.)\2\1

咦?-230 分是闹那样?

原来是要反向匹配,这时候要用到反向语句 (?!exp),改写成 ^(?!.*(.)(.)\2\1) 通过!193 分

看到还有个 ^(?!(.)+\1)|ef 骗过去的,惊了

A man, a plan

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

这题要求要匹配回文串,容易想到上一道题 Abba 的方法。用 ^(.)(.).*\2\1$ 去尝试,拿了 176 分。(虽然有反例

最简 ^(.)[^p].*\1$

Prime

The length is not part of the string. I should probably have chosen a different color.

大意是要求匹配长度为素数的字符串,这时候可以通过贪婪模式 .? 来实现,用 ^(?!(xx+?)\1+$) 拿了 285 分。

解释一下,首先分拆掉反向语句 ^(?!exp),留下 ^(xx+?)\1+$ 部分,这个部分首先尝试匹配 ^xx(xx)*$,也就是测试字符串长度能否被 2 除尽,否则依次尝试 3,4,5……,就是一个朴素的试除法判断素数。

UP:语句可以省略贪婪模式,原因不明。^(?!(xx+)\1+$),得分升到 286,开心

Four

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

观察发现,匹配的字符都有 a*a*a*a 的特点,直接以第一个字符为代表,连续匹配三次即可。语句为 (.)(.\1){3},得分 199

Order

Cheat.

出题人的描述越来越看不懂了,仔细看了好久才知道是要求匹配非递减字符序列。
想了个 ^.[^a][c-z]*$ 骗了 117 分,后来发现倒过来进行匹配更优,改写成 ^[^o].....?$ 198 分

最简 ^.{5}[^e]?$


下面全在骗分,改天慢慢研究

Triples

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

给出十进制数,要求匹配 3 的倍数的数。
这也能用正则做?
先乱搞一通,改天研究:00|4 骗了 176 分

最简 [02-5][123][257]|[07][0269]+3?$|55

Glob

出题人连描述都不写了 233
匹配出类似 *falle*ess matches unfallennessA matches B 的正则。

天,正则中的正则!果断先打个 \* 骗 58 分

最简 c$|^p|ta|[bcnrw][bnopr]

Balance

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

给出括号序列,匹配所有左右括号能完美匹配的括号序列
手工乱打 <<.>><.> 277 分

最简 .{37}|^(<(..(?!<.>$))*>)*$

Powers

In hard mode, you have to recognize any power of two.

匹配出所有长度为 2 的幂次方的字符串。
容易想到,这些字符串长度必定能被 2 整除。直接分成两段,用反向引用骗一下分,^(.+)\1$ 拿了 52 分

最简 ^(?!(x(xx)+)\1*$)

Long count

题目给出一个 01 字符串,要求精确匹配。
我直接复制左边的字符串来用了 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111,前面可以优化,变成 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111,拿了 206 分,我好无耻

仔细观察一下,可以简化为 ((.+)0\2+1){8}

Alphabetical

看不出什么规律,匹配了开头两个字符,^a[se] 骗了 94 分

最简 .r.{32}r|a.{10}te|n.n..

Powers 2

Or 3.

和前面某题差不多,要求匹配 3 的幂次方长度的字符串。
直接改改上题表达式 ^(.*)\1\1$ 拿了 70 分。


感觉自己真是,完全不会正则啊~
还是得好好学习一下


本文采用 CC BY-NC-SA 3.0 Unported 协议进行许可
本文链接:https://i-meto.com/regex-golf/