【问题标题】:RegEx for validating float numbers用于验证浮点数的正则表达式
【发布时间】:2019-05-21 03:23:50
【问题描述】:

我正在为班级制作一个抵押贷款计算器。我有一种方法可以确定该值是否为浮点数、同上有效数字、同上整数。如果号码是有效号码

我尝试过使用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

我希望任何不包含小数的浮点数都为假?方法,但如果我不输入小数,我的程序似乎并不关心。

【问题讨论】:

  • 你很少想在 Ruby 正则表达式中使用 ^$line 的开始/结束),你几乎总是需要 \A\zstring) 的开头/结尾。看看Kernel#FloatKernel#Integer 方法。
  • 我假设你不会遇到float?(1.2e3)。我理解为什么您可能想要确认某些值是整数(例如,偿还贷款的期限数),但我不明白为什么您需要确定某个值是否为浮点数。例如,如果输入的是贷款金额,只需将其转换为浮点数,而不关心它是作为浮点数还是整数输入。由于舍入误差,使用浮点数进行财务计算通常不是一个好主意。这就是为什么我们有BigDecimal

标签: regex ruby string regex-group


【解决方案1】:

执行此操作的简单而可靠的方法是根本不使用正则表达式。为什么你关心字符串的样子?您真正关心的是 Ruby 是否真的可以将该字符串 convert 转换为 int/float。为此使用内置的IntegerFloat 方法:

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

【讨论】:

    【解决方案2】:

    您可能只想将您的表达式包装在一个捕获组中,它会传递浮点数,而其他人则失败。

    测试代码

    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 演示

    这个 sn-p 表明我们可能有一个有效的表达式:

    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}`);
        });
    }

    正则表达式

    如果这不是您想要的表达式,您可以在regex101.com 中修改/更改您的表达式。

    正则表达式电路

    您还可以在jex.im 中可视化您的表达式:

    性能测试

    此脚本针对表达式返回浮点数的运行时间。

    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. ? ");

    【讨论】:

    • 我比我现在使用的更喜欢这个表达。我有一个问题是/([0-9]+\.[0-9]+)/m中的“m”@
    • 请注意[0-9]\d 相同。我认为 Ruby 不支持 g 修饰符。此外,在没有 JS 标签的情况下提供 JS 演示的用处值得怀疑。
    • 按书面形式回答问题,但在 Ruby 中你永远不需要浮点正则表达式(除非你正在做一些非常特殊的格式化工作,而这个提问者似乎不需要)。
    猜你喜欢
    • 1970-01-01
    • 2012-09-20
    • 1970-01-01
    • 1970-01-01
    • 2020-10-09
    • 1970-01-01
    • 2011-06-17
    • 1970-01-01
    相关资源
    最近更新 更多