[size=medium][b]使用正则表达式处理浮点数问题[/b][/size]

在这个例子中,将要显示给大家呼喝避免初学者使用正则表达式时会犯的错误。举个例子,我们要建立一个正则表达式,功能是能匹配任意浮点数。我们的正则表达式也应该匹配整数,和浮点数(其整数部分没有给出例如:0)。这里并不尽力去匹配带有煮熟的数字,例如:1.5e8(150百万使用科学计数法)。
初一想,下面的正则表达式好像可以,[-+]?[0-9]*\.?[0-9]*.它定义了一个正负号可选的浮点数,接着是可选的数字序列(整数部分),接下来是一个可选的.(dot),接下来是另外一个可选的数字序列。
根据上面的描述我们可能就会发现一个问题,上面的所有正则表达式都是可选的。这个正则表达式将考虑一个正负号,或者一个.(dot)作为一个有效的浮点数。事实上,它甚至考虑将空串作为一个合法的浮点数。如果这个表达式用在一种脚本语言中例如perl或者php中来验证用户输入将会引起严重的问题。
没有避开.(dot)也是一个常见的错误,一个.(dot)没有避开,它将匹配任意字符,包括.(dot)。如果我们没有避开.(dot)4.4将要被考虑为一个浮点数,当然4f/^4也将被考虑成浮点数。
当我们创建正则表达式的时候,考虑它不应该匹配什么内容也是很重要的,甚至比我们应该匹配什么内容更重要。上面的正则表达式的确会匹配一个合适的正则表达式,因为正则表达式是贪婪的。但是它也匹配很多我们不想要匹配的内容,这些内容我们应该排除的。
下面是一个比较好的尝试:[-+]?([0-9]*\.[0-9]+|[0-9]+)。这个正则表达式匹配一个可选的符号,接下来是或者跟0或者数字序列,接着是.(dot)然后是数字序列(一个浮点数有可选的整数部分)或者紧跟一个或多个数字序列(表示一个整数)。
我们可以优化这个正则表达式:[-+]?[0-9]*\.?[0-9]+
如果你要匹配附带有指数的数字,你可以用:[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?
注意到这里使用了圆括号的组合将整个指数部分可选,而不是使得指数部分的每个组成都可选。
最后,如果你想要验证是否一个特定的串是否包含浮点数,而不是在一个很长的文本中寻找浮点数,你将不得不使用锚定你的正则表达式^[-+]?[0-9]*\.?[0-9]+$ 或者 ^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$。