尽管eprep命令看上去挺简洁,但是对于比较复杂的文本处理,数据挖掘,甚至要进行二次处理来说,就只有不停借助管道,可读性和灵活性就相对不好维护,而其它比如perl,python之类的脚本语言对于正则表达式支持得更加完备
匹配字符串
假如想确认一个字符串里是否全部是数字,其实perl的松散和python的优美在正则表达式里也能体现出来,perl的规矩是根据上下文来确认变量的类型,这样就导致明明是整型字符串,而进行四则运算,perl会自动根据上下文当作整型来操作,而python就会明确报错,类型有问题,有的人喜欢任性的perl,也有的人喜欢可读性更好的python
下面是一段perl简单的实现
#!/usr/bin/perl -w if ($ARGV[0] =~ /^\d+$/){ print "Numbers!\n"; } else { print "Not Numbers!\n"; } lihui@2015 ~ $ ./hi.pl 33131 Numbers! lihui@2015 ~ $ ./hi.pl 33131as32 Not Numbers!
这里的=~符号就用来在运行脚本的参数中搜索是否满足正则表达式^\d+$,这里匹配能够保证从头到尾全部都是数字;假如需求更麻烦一点,正负小数情况也能够接受,也就是比如+3.232和-54.2类似也算Numbers
首先前面是否有正负号未知,可以用 ^[+-]?
然后整数部分稍微简单全数字,用 \d+
最后小数部分首先是小数点,然后是小数部分,但是也有可能根本没小数部分,也没小数点,所以整个部分就是可选的,所以需要括起来用?来匹配,即(\.\d+)?$
综合起来就是
#!/usr/bin/perl -w if ($ARGV[0] =~ /^[+-]?\d+(\.\d+)?$/){ print "Numbers!\n"; } else { print "Not Numbers!\n"; } lihui@2015 ~ $ ./hi.pl -1 Numbers! lihui@2015 ~ $ ./hi.pl -1.0 Numbers! lihui@2015 ~ $ ./hi.pl +1.0a Not Numbers! lihui@2015 ~ $ ./hi.pl 1.07 Numbers!
假如此时,你还不满足,想分别打印出整数部分和小数部分的值,在程序中也许你想将他们分别赋给其它的变量,类似于egrep里的\1,\2,\3反向引用,perl通过变量$1,$2,$3来代替正则表达式从左到右第1,2,3个顺括号里的内容
#!/usr/bin/perl -w if ($ARGV[0] =~ /^[+-]?(\d+)(\.\d+)?$/){ print "\$1 = $1\n"; print "\$2 = $2\n"; print "Number is $1$2" } else { print "Not Numbers!\n"; } lihui@2015 ~ $ ./hi.pl 1.07 $1 = 1 $2 = .07 Number is 1.07
正则表达式里有两个括号,第一个括号是整数部分的数字部分,不包括正负号(如果有);第二个括号是小数点以及小数部分;不要怀疑为什么引号里还可以直接输出变量的值,perl一切皆有可能,但上面程序有个问题,由于是-w,警告也会爆出来,就像-Werror一样
lihui@2015 ~ $ ./hi.pl -3 $1 = 3 Use of uninitialized value $2 in concatenation (.) or string at ./hi.pl line 5. $2 = Use of uninitialized value $2 in concatenation (.) or string at ./hi.pl line 6. Number is 3
因为假如没有小数部分,$2就根本不存在,那么就会当作错误,假如去掉-w,$2 = 后面会是空,所以写程序一定要严格,多做判断,啰嗦一点就这么写~!
#!/usr/bin/perl -w if ($ARGV[0] =~ /^[+-]?(\d+)(\.\d+)?$/){ print "\$1 = $1\n" if $1; print "\$2 = $2\n" if $2; if ($2) { print "Number is $1$2"; } else { print "Number is $1"; } } else { print "Not Numbers!\n"; } lihui@2015 ~ $ ./hi.pl -3 $1 = 3 Number is 3