请教到底如何真的掌握“正则表达式”以及人和人的认知差距真的会有这么大吗?

2021-09-25 00:20:00 +08:00
 laydown

昨晚入睡前,搜 Twitter 上关于“正则”的推文,突然看到有个人发了一条推,问了一个关于正则表达式写法的问题,问题原文是:“匹配一个字符串,其由且仅由偶数个 0 和奇数个 1 组成,不论顺序。”,我当时很惊讶,正则还能拿来进行这种奇数个或者偶数个字符出现的次数的吗,看了一下回复,真的有不少人给出了他们的答案,其中有一条回复很简短,正则表达式如下:(?=^1*((01*){2})$)(^([01]{2})[01]$)。经过实测,结果是符合提问者要求的。这次我真的被震惊到,真的是天外有天人外有人,当我以为自己对正则的写法略懂还在沾沾自喜的时候,其他人更是随随便便就写了一条如果我不用工具就测试不出来是否正确的表达式。他到底是怎么想到的,甚至在我用工具进行测试,再对表达式的字符逐个进行分析,还是不觉得自己真理解这样的写法为什么就能达到提问者的要求。这让我的挫败感更加深了。

大家如果只看这个正则的问题,也都能很容易地写出来符合要求的表达式吗?

3338 次点击
所在节点    问与答
31 条回复
nlzy
2021-09-25 12:51:30 +08:00
这题也可以看成是 DFA 的典型例题,就像 #15 说的:“作业基本都是这种东西”。而 DFA 和正则表达式可以互相转换,所以构造出 DFA 再一步步转成正则就可以做出来了。

我做了做,得到了 ^(0(11)*0)*(1|01(11)*0)(0(11)*0)*((1|01(11)*0)(0(11)*0)*(1|01(11)*0)(0(11)*0)*)*$

最后的结果我自己也看不懂,这只是我机械地套用公式得到的,所以楼主没必要为看不懂这些正则而灰心丧气啦。
ch2
2021-09-25 12:59:53 +08:00
@MegrezZhu #10 不,正则表达式比 context-free 能力更弱
ipwx
2021-09-25 14:45:24 +08:00
@ch2 DFA 还好。一旦用上比如贪婪或者前项断言,正则就会变成 NFA,那效率就 hhhh
agagega
2021-09-25 17:06:29 +08:00
很正常。

中学和大学学数学物理的时候,我一直有种强烈的感觉:课本上学的和题目里的是两个东西。书上讲的是什么叫不等式,什么叫微分积分。但作业里的习题本质上考验的是另一种东西,只不过套上了不同知识的皮。你要么知道这个「另一种知识」,要么足够聪明能自己悟出来,否则学了书本也没有用。
WuSiYu
2021-09-25 19:31:57 +08:00
DFA 手推版:^(0(11)*0)*(01(11)*0|1)((0(11)*0)*|(0(11)*10|1)(0(11)*0)*(01(11)*0|1))*$
也就是形式语言中的正则表达式(只有乘、加、闭包、括号),可见和工业界的 regex 还是有比较大的风格差异
性能角度,DFA 理论上是更快的,不过在上班我肯定写个 for
ecnelises
2021-09-25 19:32:51 +08:00
前面用到了额外断言的答案比较好理解。解释一下楼上面这个答案吧:

^(0(11)*0)*(1|01(11)*0)(0(11)*0)*((1|01(11)*0)(0(11)*0)*(1|01(11)*0)(0(11)*0)*)*$

如果让 X=(0(11)*0), Y=(1|01(11)*0),那么整个其实是 X*YX*(YX*YX*)* (开头结尾的符号省略了,不影响理解),而这个的意思其实是出现奇数个 Y 间隔任意个 X.

为什么 X 可以随意出现呢?因为 X 一定代表了偶数多个 0 和 1,无论是我们想要的奇数个 1 还是偶数个 0,减去偶数个 0 和偶数个 1 都没关系。Y 也不难理解了,因为穷举了所有奇数个 1 出现的情况。奇数个 1 出现奇数次还是奇数,所以满足要求。
ZeroDu
2021-09-25 20:31:17 +08:00
工作两三年了正则这个东西真的很奇葩,学不会...。javaer
kikikiabc
2021-09-25 20:40:40 +08:00
天书?恐怕过几天自己都看不懂。用 python 写过正则表达式,一定要用 verbose 模式,就是表达式里面支持换行和注释,才能把一些复杂的表达式说清楚
charlie21
2021-09-25 20:50:40 +08:00
可以不会 solution,但要会评估 feasibility (和买个 solution 该出的价格)
Jooooooooo
2021-09-25 20:54:14 +08:00
总感觉正则无法一眼看出是干嘛的..
yaleyu
2021-09-26 07:55:42 +08:00
个人觉得,太复杂的正则,用来学习不错,写到代码里面,别说别人很难理解,过段时间自己再看估计都要迷糊了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/804050

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX