正则有意思
Table of Contents
2 事情的经过是这样的:
- 毕竟大家正则入门靠的都是这个嘛,要学会更高级的正则的写法,那么就从平衡组(Balancing Group)开始吧,好像并不难呀,为啥总也测试不通过呢?
- 找解决方法的时候,发现正则的限定符(quantifier)除了贪婪(greedy),懒惰(lazy)以外,还有个自私(possessive)的毛病。
- 贪婪和懒惰我都懂,自私是个什么鬼,看起来不难的样子,先搞定它。
- 然后发现要想正确使用“自私”限定符,需要先弄明白回溯(backtracking)是怎么回事。
- 接着又发现要想搞清楚回溯,就要知道=NFA=(Nondeterministic Finite Automaton 非确定有穷状态机)的工作过程。
- 既然研究了=NFA=,那=DFA=(Deterministic Finite Automaton 确定有穷状态机)必然也不能放过的。
- 大功告成,等等,我开始是要干什么的来着?赶紧“回溯”。
- 平衡组?哦,原来只有.net才支持啊,微软的黑科技之一哎。
3 事情就这样结束了:
- 再次印证了“Erlang的文档中有大量的宝贝”这一真理,比如关于正则的语法,介绍的清楚而周全。同样,微软的文档良心也是大大的,相比之下,python的re模块的文档就只是个备忘录水平(当然吹毛求疵是不好的,讲道理,python的文档算得上是不错的了)。
- 正则的手段就两种,匹配(match)和捕获(capture),虽然之前一直都隐约知道,但直到我了解了=(?:=之后才真正有体会。
- 在子表达式内部可以单独设置正则选项。设置选项有两种写法,我更喜欢这一种=(?imsx-imsx:exp)=
- 正则是可以进行条件判断的,条件语句有四种,子模式的引用,递归的引用,断言和伪条件=DEFINE=,这个=DEFINE=永远为=假=,所以这个=DEFINE=就真的是=define=了,它通常就被用来定义一些子表达式。
- 那么还有哪些表达式永远为真或者永远为假呢?=(?=)=,=(?<=)=,=(?!)=,=(?<!)=这四个。熟悉么,它们就是断言哎,那么现在问题来了,你知道它们到底哪些为真哪些为假吗?
- PCRE虽然没有平衡组,但是支持递归,就像递归和栈能相互转换一样,平衡组能解决的问题用递归也能做到。
- 后向引用(Back References)和子例程(subroutine)看起来是挺像的,只不说一个是匹配了之前匹配的内容,一个匹配了之前的模式。
- 用=(?>=表示的原子组(Atomic Grouping)在微软的文档里又叫非回溯子表达式(nonbacktracking subexpression),既然是原子的,自然就不给回溯了,很贴切。
- 看到非回溯,自然就会想到自私限定符,这个符号的意思就是“不回溯”,所以如果原子组只需要用一次的话,就可以用自私符改写。
- 表达式的编号可以通过数括号来确定,有时候希望子表达式里能重复编号,这时候就可以用=(?|=了。但它和子例程同时出现时要注意编号。
- 微软的正则有个神奇的替换功能,跟vscode里的查找替换一模一样啊。