Совпадение десятичных чисел - PullRequest
3 голосов
/ 05 июня 2019

Я бы хотел сопоставить десятичные числа, например:

0.0
0.12
1.00
1.12
-0.123
-1.000
-1.123

без сопоставления отрицательных нулей: -0.0 или -0.00, -0.000 и т. Д.

Я понятия не имею, как расширить регулярное выражение /^-?[0-9]+\.[0-9]+$/, чтобы не допустить отрицательных нулей.

UPDATE:

  • Не допускаются начальные нули: 01,1 или -01,1
  • Требуются целые и дробные символы (.5 или 5. не допускаются)

Ответы [ 3 ]

3 голосов
/ 05 июня 2019

IIUC, вам просто нужно добавить отрицательный прогноз (?!-0\.0+$):

^(?!-0\.0+$)-?\d+\.\d+$

Пример:

echo '0.0
0.12
1.00
1.12
-0.123
-1.000
-1.123
-0.00
-0.0
-0.000010
-12.34
' | perl -lne 'print if /^(?!-0\.0+$)-?\d+\.\d+$/'
#0.0
#0.12
#1.00
#1.12
#-0.123
#-1.000
#-1.123
#-0.000010
#-12.34
0 голосов
/ 05 июня 2019

Вот грубый, но эффективный подход: перечислите все возможности и используйте чередование.

^(-\d+\.\d*[1-9]\d*|-\d*[1-9]\d*\.\d+|^\d+\.\d+)$

Обратите внимание, что ваши правила допускают совпадение начальных нулей на числе, например, 01.1 или -01.0,Вы можете отклонить их с еще более грубыми

^(-?0\.\d*[1-9]\d*|-[1-9]\d*\.\d*[1-9]\d*|-[1-9]\d*\.\d+|^[1-9]\d*\.\d+|0.0+)$

Тестами:

const permissive = /^(-\d+\.\d*[1-9]\d*|-\d*[1-9]\d*\.\d+|^\d+\.\d+)$/;
const strict = /^(-?0\.\d*[1-9]\d*|-[1-9]\d*\.\d*[1-9]\d*|-[1-9]\d*\.\d+|^[1-9]\d*\.\d+|0.0+)$/;

`
0.0
0.00
0.001
0.12
1.00
1.12
-0.123
-1.000
-1.123
10.10
2.2
-2.2
0.00
-10.010
0.101

-0.0
-0.00
-0.000
-2.
.0
-.0
.012
1.
12.
00.
0.

-001.0
-01.0
01.1
010.1010
000.000
00.0
`.split("\n").filter(e => e).forEach(test => 
  console.log(
    test, "=> permissive:", permissive.test(test), 
    "... strict:", strict.test(test)
  )
);
0 голосов
/ 05 июня 2019

Вы можете использовать

^-?(?:0*[1-9][0-9]*\.[0-9]+|0\.0*[1-9][0-9]*)$

https://regex101.com/r/z51Jpu/5

Идея состоит в том, чтобы после сопоставления - соответствовать либо ненулевое значение в целочисленной части, либо совпадать с нулемв конце концов следует ненулевое значение.

  • ^-? - начало строки, необязательно -
  • (?:[1-9]\.[0-9]*|0\.0*[1-9][0-9]*) - совпадение либо:
    • 0*[1-9][0-9]*\.[0-9]* ненулевая целочисленная часть, за которой следует десятичная часть, или
    • 0\.0*[1-9][0-9]* - нулевая целочисленная часть с десятичной частью, которая где-то имеет ненулевое значение
  • $ - Конец строки

Можно также посмотреть цифру от 1 до 9 где-то в строке, а затем использовать свой оригинальный шаблон:

^-?(?=[0.]*[1-9])[0-9]+\.[0-9]+$
   ^^^^^^^^^^^^^^

https://regex101.com/r/z51Jpu/6

...