正则表达式常见错误
如果用 [0-9]* 匹配 'a 1234 num', 备用状态是否包括 'a .1234 num'(点号代表位置) ? (p.164)
答案是否定的. 星号限定的部分总是能够匹配. 如果整个表达式都由星号控制, 它就能够匹配任何内容. 在字符串的开始位置, 传动机构对引擎进行第一次尝试时的状态, 当然算匹配成功. 在这种情况下, 正则表达式匹配 '.a 1234 num', 而且在此处结尾 --- 它根本没有触及到那些数字.
如果没答对也不要紧, 因为这种情况还是有可能发生的. 如果在表达式中, [0-9]* 之后还出现了某些元素, 因为它们的存在, 引擎在达到下面状态之前无法获得全局匹配:
______________________________
'a .1234 num' | .[0-9]*
--------------------------------------
那么, 尝试 '1' 会生成下面的状态:
______________________________
'a .1234 num' | [0-9]* .
--------------------------------------
有序多选结构的陷阱
如何匹配一个月中的日期? 假设一个月固定有 31 天.
m/(0?[1-9]|[12][0-9]|3[01])/ ; Wrong当这个表达式匹配 Jun 31 的时候, 其实得到的匹配是 3. 因为多选分支会先尝试 0?[1-9], 因此得到匹配, 并终止了其它尝试.
把能够匹配的最短数字放到最后, 就可以解决问题.
正确的表达方法是:
m/([12][0-9]|[3][01]|0?[1-9])/ ; Right
fd