RegEx для проверки чисел с плавающей точкой - PullRequest
1 голос
/ 19 мая 2019

Я делаю ипотечный калькулятор для класса.У меня есть метод, чтобы определить, является ли значение с плавающей точкой, то же самое действительное число, то же самое целое число.Если число является действительным числом

, я попытался использовать if valid_number?(apr) && float?(apr), который возвращает true для целых чисел.

def valid_number?(input)
  integer?(input) || float?(input)
end

def integer?(input)
  /^\d+$/.match(input)
end

def float?(input)
  /\d/.match(input) && /^\d*\.?\d*$/.match(input)
end

apr = gets.chomp

if valid_number?(apr)
  if float?(apr)
    puts "Is #{apr}% correct? Y or n"
  end
end

Я ожидаю, что все, что не содержит десятичной дроби, будет ложным для числа с плавающей запятой?метод, но если я не поставлю десятичную, моя программа, кажется, не заботится.

Ответы [ 2 ]

0 голосов
/ 20 мая 2019

Простой и надежный способ сделать это - вообще не использовать регулярное выражение. Почему тебя волнует, как выглядит строка? Что вас действительно волнует, так это то, что Ruby может преобразовать эту строку в int / float. Для этого используйте встроенные методы Integer и Float:

def integer?(input)
  Integer(input)
  true
rescue
  false
end

def float?(input)
  Float(input)
  true
rescue
  false
end

И какой смысл проверять, можно ли преобразовать строку, если вы не получите преобразованное значение в конце? Объедините все:

def number string
  begin
    return Integer(string)
  rescue
    return Float(string)
  end
rescue
  nil
end

if num = number input
  # now num is some number type: Fixnum/Bignum/Float
end
0 голосов
/ 19 мая 2019

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

Тестовый код

re = /([0-9]+\.[0-9]+)/m
str = '1
1000
1.00
1000.00'

# Print the match result
str.scan(re) do |match|
    puts match.to_s
end

Для тестирования вам может не потребоваться многострочный флаг, и m можно безопасно удалить.

Демонстрация JavaScript

Этот фрагмент показывает, что мы, вероятно, имеем правильное выражение:

const regex = /([0-9]+\.[0-9]+)/gm;
const str = `1
1000
1.00
1000.00`;
let m;

while ((m = regex.exec(str)) !== null) {
    // This is necessary to avoid infinite loops with zero-width matches
    if (m.index === regex.lastIndex) {
        regex.lastIndex++;
    }
    
    // The result can be accessed through the `m`-variable.
    m.forEach((match, groupIndex) => {
        console.log(`Found match, group ${groupIndex}: ${match}`);
    });
}

RegEx

Если это не было вашим желаемым выражением, вы можете изменить / изменить выражения в regex101.com .

enter image description here

RegEx Circuit

Вы также можете визуализировать свои выражения в jex.im :

enter image description here

Тест производительности

Этот скрипт возвращает время выполнения числа с плавающей запятой относительно выражения.

const repeat = 1000000;
const start = Date.now();

for (var i = repeat; i >= 0; i--) {
	const regex = /([0-9]+\.[0-9]+)/gm;
	const str = `1000.00`;
	const subst = `$1`;

	var match = str.replace(regex, subst);
}

const end = Date.now() - start;
console.log("YAAAY! \"" + match + "\" is a match ??? ");
console.log(end / 1000 + " is the runtime of " + repeat + " times benchmark test. ? ");
...