Perl学习笔记–Building a RegExp

今天看了一个设计文档,是关于怎么设计一个数据库表来模拟配置环境的,觉得设计的挺好的,估计能和数据库原理那本书对上。看了一天,头有点大,回家前写篇Perl学习笔记吧,就当翻译作业好了。Todd在公司Wiki上建了一个Page,里面有他写的一些很实用的脚本,以后再学。

 

目的 :匹配数字(Numeric),可以是整型,可以是浮点,可以是科学计数,有可能带正负号。

我先摘录一下整体思路,这个思路不限于匹配数字,这是一个构建正则 表达式的通用思路:

  1. 详细的表述需求(Specify the tasks in detail)
  2. 把问题分解成子问题(Breaking down the problem into smaller parts)
  3. 把子问题用正则表达式表示出来(Translating the small parts into regexps)
  4. 整合用于解决子问题的正则表达式(Combining the regexps)
  5. 优化整个后的结果(Optimizing the final combined regexp)

其实很多东西都是相通的,所以要多学涉猎一些学科。上面提出来的5个步骤在算法导论中也提到过,这就是典型的Divide and Conquer的思路。或许现实生活中碰到的很多问题也是这样的思路呢。好了,不说废话了,我们一步步来:

 

Step1:在目的里面已经比较详细了,再补充一点,我们还可以换一个角度考虑,有时候不能正面表述一个事物的时候可以用反面来描述,比如,匹配数字就意味着不能匹配字符串!

 

Step2:子问题再目的中也给的比较明确,一共就两类,整数和浮点数,每一类都有可能是使用科学计数法的,有可能是带正负号的。而且正负号一定出现在开头/^/,而指数部分一定出现在结尾/$/。

 

Step3:正负号是可选的,所以是/[+-]?/。整数的表达是/d+/。小数比较复杂,有3种形式,比如12., .12, 1.2 。对应这3种情况,分别写出正则表达式: /d+./, /.d+/和/d+.d+/。所以对于无指数部分的浮点数表达就是:

/[+-]?(d+.| .d+| d+.d+)/  ,我们来试验一下下:perl -e ‘print $1 if 123.45=~/[+-]?(d+.| .d+| d+.d+)/’;我们希望匹配123.45,可是结果是匹配123. !!为什么呢,问题出在匹配的时候,有多条道路选择的时候,从左边开始走,只要走通,就不去尝试其他的选择了。因为123.已经匹配了,所以就不去看下面的了,就错了!在使用’|'操作时一定要小心,尽量把条件更严格(更精确匹配)的表达式放在前面。这里我们必须把/d+.d+/放在/d+./的前面。

-bash-3.00$ perl -e ‘print $1 if 123.45=~/[+-]?(d+.d+|d+.|.d+)/’
123.45

现在就剩下指数部分了,/([eE][+-]?d+)?/,注意指数也是有正负的哦,而且指数部分是可选的!

 

Step4:从逻辑上讲,这道题目可以表达成 /^(optional sign)(integer|f.p. mantissa)(optional exponent)$/;所以最后的正则表达式就是:

/^[+-]?(d+.d+|d+.|.d+|d+)([eE][+-]?d+)?$/
Step5:这里倒没有什么优化的地方,有一点提一下,一定要写注释,不然过几天,自己都看不懂了-:)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章