Регулярное выражение для значащих цифр определенного размера (любой язык)

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

Я хотел бы, чтобы регулярное выражение терпело неудачу при заданном количестве значащих цифр (Max), но проходило меньше, чем Max. Я хотел бы, чтобы он работал как с точками, так и с запятыми (французскими) десятичными разделителями.

Таким образом, для 15 значащих цифр должно пройти:
0
0,00
1
-1
1,23456789012345
10,2345678901234
12,3456789012345
-123,4
-12,34< br> -1,33
-1,33
-123456789012345
-1234567890123450
-12345678901234,50
12345678901234,50
123456789012345,00

// should fail:
-1234567890123456
-12345678901234.56
12345678901234.56
123456789012345.60
1.234567890123456
12.34567890123456
123456789012340.6
123456789012300.67
123456789012300000000000.67
10000000000010000000001000010000000001.22

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

^(?!(?:.*?[1-9]){15,})([-+]?\s*\d+[\.\,]?\d*?)$

https://regex101.com/r/hQ1rP0/218

но вы можете видеть, что последние несколько все еще проходят, какие-нибудь указатели?


person bobbybobbobbed    schedule 19.10.2017    source источник
comment
У вас есть конфликты. -1234567890123450 состоит из 16 цифр и является допустимым, в то время как -1234567890123456 также состоит из 16 цифр и ошибочно   -  person ctwheels    schedule 19.10.2017
comment
Это верно, так как -1234567890123450 состоит из 16 цифр, но заканчивается на 0, то есть только 15 значащих цифр, относящихся к экспоненциальному обозначению. Где -1234567890123456 имеет 16 цифр, относящихся к экспоненциальному представлению.   -  person bobbybobbobbed    schedule 19.10.2017
comment
0s перед десятичной дробью являются значимыми.   -  person ctwheels    schedule 19.10.2017
comment
^-?(?=\d{1,15}(?:[.,]0+)?$|(?:(?=.{1,16}0*$)(?:\d+[.,]\d+))).+$, с вашей странной логикой значащего числа, однако ^-?(?=\d{1,15}(?:[.,]0+)?0*$|(?:(?=.{1,16}0*$)(?:\d+[.,]\d+))).+$   -  person ctwheels    schedule 19.10.2017
comment
Дарн, не могу обновить вопрос. Но я хочу иметь возможность игнорировать конечные нули. Это означает, что я хочу подсчитать значащие цифры, но игнорировать их, если они являются конечными нулями. Итак, в моем случае игнорируйте 0 перед десятичным числом, если нет ненулевых десятичных чисел, но включайте их, если они есть. Я пытаюсь поймать случай, когда научная запись неточно округляется.   -  person bobbybobbobbed    schedule 19.10.2017
comment
@ctwheels. это работает очень хорошо, кажется, отлично улавливает примеры. Спасибо (принял бы как ответ, если бы вы добавили его, все еще тестируя еще несколько примеров). Это действительно полезно для определения ограничений javascript.   -  person bobbybobbobbed    schedule 19.10.2017


Ответы (1)


Код

Для реальной научной записи (где начальные нули имеют значение перед десятичным символом) вы можете использовать следующее

^-?(?=\d{1,15}(?:[.,]0+)?$|(?:(?=.{1,16}0*$)(?:\d+[.,]\d+)))‌.+$

Однако это следующее регулярное выражение работает для вашего случая ведущих нулей независимо от десятичной позиции.

Посмотрите, как это регулярное выражение используется здесь

^-?(?=\d{1,15}(?:[.,]0+)?0*$|(?:(?=.{1,16}0*$)(?:\d+[.,]\d+)‌​)).+$

Объяснение

  • ^ Займите позицию в начале линии
  • -? Соответствует нулю или одному из - символов буквально
  • (?=\d{1,15}(?:[.,]0+)?0*$|(?:(?=.{1,16}0*$)(?:\d+[.,]\d+))) Positive lookahead ensuring what follows matches the following
    • \d{1,15}(?:[.,]0+)?0*$ Option 1
      • \d{1,15} Match between 1 and 15 of any digit character
      • (?:[.,]0+)? Соответствует десятичному символу ,., за которым следует один или несколько 0 буквально, но либо ноль, либо один раз
      • 0* Соответствует любому количеству 0 буквально
      • $ Займите позицию в конце строки
    • (?:(?=.{1,16}0*$)(?:\d+[.,]\d+)) Option 2
      • (?=.{1,16}0*$) Ensure what follows matches the following
      • .{1,16} Соответствует любому символу от 1 до 16 раз
      • 0* Соответствует любому количеству 0 буквально
      • $ Займите позицию в конце строки
      • (?:\d+[.,]\d+) Сопоставьте следующее
      • \d+ Сопоставьте любую цифру от 1 до неограниченного количества раз
      • [,.] Совпадение с десятичным символом
      • \d+ Сопоставьте цифру от 1 до неограниченного количества раз
  • .+ Соответствует любому символу один или несколько раз
  • $ Утверждать позицию в конце строки (на самом деле не нужно, но я думаю, что это помогает для удобочитаемости)
person ctwheels    schedule 19.10.2017