Как определить число с плавающей запятой с помощью регулярного выражения - PullRequest
14 голосов
/ 19 февраля 2010

Что является хорошим регулярным выражением для обработки числа с плавающей запятой (например, типа Java с плавающей точкой)

Ответ должен совпадать со следующими целями:

 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 ]

23 голосов
/ 19 февраля 2010

Просто сделайте необязательными десятичную точку и часть E-затем-экспоненты:

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

Я не понимаю, почему вы не хотите, чтобы ведущий [+-]? тоже захватывал возможный знак, но, что угодно! -)

Редактировать : на самом деле от десятичной запятой не должно быть никаких цифр (в таком случае я думаю, что должно быть десятичной точкой и 1+ цифры после него!), поэтому явно нужна вертикальная черта (альтернатива):

(([1-9][0-9]*\.?[0-9]*)|(\.[0-9]+))([Ee][+-]?[0-9]+)?
7 голосов
/ 24 марта 2010

[Это ответ профессора]

Определение:

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

Тогда числа с плавающей точкой могут быть сопоставлены с:

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

Также было приемлемо использовать D + вместо L и добавлять [+ -]?.

Распространенной ошибкой было написать D *. D *, но это может соответствовать просто '.'.

[Изменить]
Кто-то спросил о ведущем знаке; Я должен был спросить его, почему это было исключено, но никогда не получил шанс. Так как это было частью лекции по грамматике, я предполагаю, что или это облегчило проблему (маловероятно), или есть небольшая деталь в разборе, где вы делите набор задач так, чтобы значение с плавающей запятой, независимо от знака, было фокус (возможно).

Если вы анализируете выражение, например

-5.04e-10 + 3.14159E10

знак значения с плавающей запятой является частью операции, применяемой к значению, а не атрибутом самого числа. Другими словами,

вычитать (5.04e-10)
добавить (3.14159E10)

для формирования результата выражения. Хотя я уверен, что математики могут поспорить с этим, помните, что это было из лекции о разборе.

4 голосов
/ 19 февраля 2010
3 голосов
/ 19 февраля 2010

Вот что я сдал.

(([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

A: соответствует всему, вплоть до 'e / E'
B: соответствует научной нотации

Разбивая А, мы получаем три части

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

Часть 1: допускается 1 или более цифр от 1 до 9, десятичная дробь, 0 или более цифр после десятичной дроби (цель 1)
Часть 2: допускается 0 или более цифр от 1 до 9, десятичная дробь, 1 или более цифр после десятичной дроби (цель 2)
Часть 3: допускается 1 или более цифр от 1 до 9 без десятичной дроби (см. № 4 в списке целей)


Разбивая B, мы получаем 4 основные части

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

Часть 1: для научного обозначения требуется прописная или строчная буква «е» (например, цели 8 и 9)
Часть 2: допускает необязательный положительный или отрицательный знак для показателя степени (например, цели 4, 5 и 6)
Часть 3: допускает одну или более цифр для показателя степени (цель 8)
Часть 4: позволяет научному обозначению быть необязательным как группа (цель 3)

1 голос
/ 05 октября 2017

@ Kelly S. Французский, это регулярное выражение соответствует всем вашим тестам.

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

Источник: perldoc perlretut

1 голос
/ 16 апреля 2014

@ Келли С. Френч: знак отсутствует, потому что в синтаксическом анализаторе он будет добавлен унарным выражением минус (отрицание), поэтому его необязательно обнаруживать как часть числа с плавающей запятой.

1 голос
/ 27 ноября 2013
'([-+])?\d*(\.)?\d+(([eE]([-+])?)?\d+)?'

Это регулярное выражение, к которому я пришел, пытаясь решить такую ​​задачу в Matlab. На самом деле, он не будет правильно определять числа, такие как (1.), но некоторые дополнительные изменения могут решить проблему ... ну, может быть, следующее исправит это:

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