如何使用正则表达式检测浮点数

时间:2010-02-19 02:48:42

标签: regex floating-point

用于处理浮点数的好正则表达式(例如Java的Float)

答案必须符合以下目标:

 1) 1.  
 2) .2   
 3) 3.14  
 4) 5e6  
 5) 5e-6  
 6) 5E+6  
 7) 7.e8  
 8) 9.0E-10  
 9) .11e12  

总之,它应该

  • 忽略前面的标志
  • 要求小数点左边的第一个字符为非零
  • 允许小数点两侧有0位或更多位数
  • 允许没有小数点的数字
  • 允许科学记数法
  • 允许大写或小写'e'
  • 允许积极或消极的指数

对于那些想知道的人,是的,这是一个家庭作业问题。我们在编译器的CS课程中收到了这个作业。我已经把我的答案交给了班级,并将其作为这个问题的答案发布。

[后记] 我的解决方案没有获得完全的功劳,因为它没有处理小数点左边的超过1位数。赋值确实提到了处理Java浮点数,即使这些示例都没有小数点左边的1位数。我会在自己的帖子中发布已接受的答案。

7 个答案:

答案 0 :(得分:23)

只需将小数点和E-then-exponent部分都设为可选:

[1-9][0-9]*\.?[0-9]*([Ee][+-]?[0-9]+)?

我不明白为什么你不希望领先的[+-]?捕获一个可能的标志,但是,无论如何! - )

编辑:实际上可能没有小数点左边的数字(在这种情况下,我认为必须必须为小数点

(([1-9][0-9]*\.?[0-9]*)|(\.[0-9]+))([Ee][+-]?[0-9]+)?

答案 1 :(得分:7)

[这是教授的答案]

定义:

N = [1-9]
D = 0 | ñ
E = [eE] [+ - ]? d +
L = 0 | (N D *)

然后浮点数可以与:

匹配

((L.D * | .D +)E?)| (L E)

使用D +而不是L也是可以接受的,并且可以预先加上[+ - ]?。

常见的错误是写D *。 D *,但这只能匹配'。'。

[编辑]
有人询问了一个主要标志;我应该问他为什么被排除但从未有机会。由于这是关于语法的讲座的一部分,我的猜测是它要么使问题更容易(不太可能),要么在解析问题集的地方有一个小细节,使浮点值,无论符号,是重点(可能)。

如果要解析表达式,例如

  

-5.04e-10 + 3.14159E10

浮点值的符号是要应用于值的操作的一部分,而不是数字本身的属性。换句话说,

  

减去(5.04e-10)
  添加(3.14159E10)

形成表达式的结果。虽然我确信数学家可能会争论这一点,但请记住这是一篇关于解析的讲座。

答案 2 :(得分:4)

答案 3 :(得分:3)

这是我上交的内容。

(([1-9]+\.[0-9]*)|([1-9]*\.[0-9]+)|([1-9]+))([eE][-+]?[0-9]+)?

为了便于讨论,我将标记部分

( ([1-9]+ \. [0-9]* ) | ( [1-9]* \. [0-9]+ ) | ([1-9]+))  ( [eE] [-+]? [0-9]+ )?     
--------------------------------------------------------  ----------------------    
                           A                                       B

答:匹配'e / E'的所有内容 B:符合科学记数法

分解A我们得到三个部分

 ( ([1-9]+ \. [0-9]* ) | ( [1-9]* \. [0-9]+ ) | ([1-9]+) )
   ----------1----------   ---------2----------   ---3----

第1部分:允许小数点后1到9,十进制,0或更多位数的1位或更多位数(目标1)
第2部分:允许小数点后的1-9,十进制,1位或更多位的0位或更多位数(目标2)
第3部分:允许1-9的1位或更多位数,不带小数(见目标列表中的#4)


分解B我们得到4个基本部分

 ( [eE] [-+]? [0-9]+  )?   
   ..--1- --2-- --3--- -4- .. 

第1部分:要求大写或小写'e'用于科学记数法(例如目标8和9)
第2部分:允许指数的可选正号或负号(例如目标4,5和6) 第3部分:允许指数(目标8)的1位或更多位数 第4部分:允许科学记数作为一个组(目标3)

是可选的

答案 4 :(得分:1)

'([-+])?\d*(\.)?\d+(([eE]([-+])?)?\d+)?'

这是我在Matlab中尝试解决此类任务时遇到的正则表达式。实际上,它不会正确检测(1.)之类的数字,但是一些额外的更改可能会解决问题......好吧,以下可能会解决这个问题:

'([-+])?(\d+(\.)?\d*|\d*(\.)?\d+)(([eE]([-+])?)?\d+)?'

答案 5 :(得分:1)

@Kelly S. French:标志丢失了,因为在解析器中它会被一元减号(否定)表达式添加,因此不需要将其作为浮点数的一部分进行检测。

答案 6 :(得分:1)

@Kelly S. French,这个正则表达式匹配您的所有测试用例。

^[+-]?(\d+\.\d+|\d+\.|\.\d+|\d+)([eE][+-]?\d+)?$

来源:perldoc perlretut