正则表达式常见错误

如果用 [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
   
posted @ 2011-08-14 14:33  walfud  阅读(1189)  评论(0编辑  收藏  举报