【问题标题】:Evaluate decimal spaces in a number using regex C++使用正则表达式 C++ 计算数字中的小数位
【发布时间】:2018-06-21 14:45:25
【问题描述】:

我想检查一个十进制数是否符合预定义的标准。我使用了以下正则表达式 ^[+-]?[0-9]+(.[0-9]{2,4})$ ,但它似乎不适用于 C++。我已经尝试了许多正则表达式验证解决方案,它可以按预期工作。例如,如果我有数字 0.00000,则输出应为 false,另一方面,如果数字为 0.00,则输出应为 true。在我的情况下,输出似乎没有检测到任何东西。这是我的源代码,你能帮忙吗?谢谢。

void detectFormatConsistency()
{
    std::regex dbl("^[+-]?[0-9]+(\\.[0-9]{2,4})$");
    std::smatch matches;
    int detected = 0;
    for(unsigned int index = 0; index < mixedDistro.size(); index++)
    {
        double currentValue = mixedDistro[index];
        std::string test = std::to_string(currentValue);
        if(std::regex_search(test, dbl)) \\I also tried with match
        {
            detected++;
        }
    }
    printf("Number of points detected: %d\n", detected);
}

更新:以下源代码现在可以按预期工作:

void detectFormatConsistency()
{
    std::regex dbl("^[+-]?[0-9]+(\\.[0-9]{2,4})$");
    std::smatch matches;
    int detected = 0;
    for(unsigned int index = 0; index < mixedDistro.size(); index++)
    {
        double currentValue = mixedDistro[index];
        std::string test = tostring(currentValue);
        if(std::regex_match(test, dbl))
        {
            detected++;
        }
    }
    printf("Number of points detected: %d\n", detected);
}



  //https://stackoverflow.com/questions/13686482/c11-stdto-stringdouble-no-trailing-zeros     
  //Thanks to: @Silencer
    template<typename T>
    std::string tostring(const T &n) {
        std::ostringstream oss;
        oss << n;
        std::string s =  oss.str();
        unsigned int dotpos = s.find_first_of('.');
        if(dotpos!=std::string::npos){
             unsigned int ipos = s.size()-1;
            while(s[ipos]=='0' && ipos>dotpos){
                --ipos;
            }
            s.erase ( ipos + 1, std::string::npos );
        }
        return s;
    }

感谢大家的帮助!

【问题讨论】:

  • 正则表达式中的任何内容都不会阻止 0.0000 匹配。它遵循这种模式,在. 之前有一个0,后面有4 个。 0.00 不能在另一边匹配,因为后面只有 2 个 0 而您代码中的正则表达式要求至少 3 个。
  • 我会检查mixedDistro 的值。此数组double vals[] = {0.00, 0.0000, 0.0, 0 }; 中的所有值都由std::to_string 转换为0.000000
  • 您应该使用std::regex_match,因为std::regex_search 匹配任何子字符串。
  • 此外,您问题中的正则表达式与代码中的正则表达式不同,并且 两者 都允许您说应该拒绝的模式...
  • “我已经尝试了许多正则表达式验证解决方案,它可以按预期工作。” - 你能提供一个以便我们比较吗?

标签: c++ regex decimal


【解决方案1】:

std::to_string 的结果与printf("%f") 相同的字符串将输出到控制台,后者使用默认的 6 位精度。

所以你的测试设置不合适,你应该改用字符串数组。

旁注:请注意,在 C++ 中,所有双 文字 0.00.000.000、... 都会产生相同的双精度值(即尾随零是只是不相关)。实际上,你总是有 64 位来放置你的值,分布在符号位、指数和尾数上——对于所有具有相同指数的值,你总是具有完全相同的精度。详情请查看IEEE 754

【讨论】:

    【解决方案2】:

    如果你使用字符串,我觉得你的方法很好

    bool checkFormatConsistency(const string& d) {
        static std::regex dbl("^[+-]?[0-9]+(\\.[0-9]{3,4})$");
        return std::regex_search(d, dbl);
    }
    
    int main() {
        vector<string> tests = {
            "0.00", "0.000", "0.0000", "0.00000", "10", "10.1", "-1000", "-99.99", "-345.236"
        };
        for (const string& test : tests) {
            cout << test << " -> " << (checkFormatConsistency(test) ? "ok" : "not ok") << endl;
        }
    
        return 0;
    }
    

    输出:

    0.00 -> not ok
    0.000 -> ok
    0.0000 -> ok
    0.00000 -> not ok
    10 -> not ok
    10.1 -> not ok
    -1000 -> not ok
    -99.99 -> not ok
    -345.236 -> ok
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-03
      • 1970-01-01
      • 2012-12-04
      相关资源
      最近更新 更多