【问题标题】:Regex fails to extract a double parameter substring from a string正则表达式无法从字符串中提取双参数子字符串
【发布时间】:2014-11-04 15:33:29
【问题描述】:

我正在尝试使用 Regex 库工具从文本文件中提取双精度和整数参数。这是捕获我收到的“std::regex_error”消息的最小代码:

#include <iostream>
#include <string>
#include <regex>

int main ()
{
  std::string My_String = "delta = -002.050";
  std::smatch Match;
  std::regex Base("/^[0-9]+(\\.[0-9]+)?$"); 

  std::regex_match(My_String,Match,Base);

  std::ssub_match Sub_Match = Match[1];
  std::string Sub_String = Sub_Match.str();
  std::cout << Sub_String << std::endl;

  return 0;
}

我对 Regex 库不太熟悉,也找不到任何立即有用的东西。知道是什么原因导致此错误消息吗?为了编译我的代码,我使用启用了 -std=c++11 的 g++。但是,我确信问题不是由我的 g++ 编译器引起的,正如the answers given to this earlier question 中所建议的那样(我试过several g++ compilers here)。

我希望从字符串“delta = -002.050”中得到“-002.050”,但我得到了:

在抛出 'std::regex_error' 的实例后调用终止 什么():正则表达式错误 中止

【问题讨论】:

  • 到底是什么问题,你期望的输出是什么,你得到了什么?
  • 谢谢。我刚刚编辑了我的帖子。

标签: c++ regex string c++11


【解决方案1】:

假设您有 gcc4.9(旧版本不附带支持 &lt;regex&gt; 的 libstdc++ 版本),那么您可以通过将 regex 更改为

std::regex Base("[0-9]+(\\.[0-9]+)?");

这将捕获输入中浮点数的小数部分以及小数点。

您原来的regex 存在一些问题。我认为领先的/ 是一个错误。然后你试图通过将正则表达式括在^...$ 中来匹配整个字符串,这显然不是你想要的。

最后,由于您只想匹配输入字符串的一部分,而不是整个内容,因此您需要使用regex_search 而不是regex_match

std::regex Base(R"([0-9]+(\.[0-9]+)?)"); // use raw string literals to avoid
                                         // having to escape backslashes

if(std::regex_search(My_String,Match,Base)) {
  std::ssub_match Sub_Match = Match[1];
  std::string Sub_String = Sub_Match.str();
  std::cout << Sub_String << std::endl;
}

Live demo


我希望从字符串“delta = -002.050”中得到“-002.050”

为此,请将上例中的正则表达式修改为

std::regex Base(R"(([+-]{0,1}[0-9]+\.[0-9]+))");

上面将匹配单个可选的前导 +- 符号。

【讨论】:

    【解决方案2】:

    前导正斜杠看起来不正确。此外,由于前导 ^ 和尾随 $,您似乎正在尝试匹配整行,但我不确定这是否是您想要的。此外,您的表达式与负号不匹配。

    试试这个:

    std::regex Base("-?[0-9]+(\\.[0-9]+)?$");
    

    【讨论】:

      【解决方案3】:

      我认为您遇到了错误,因为 what 在 smatch 对象中
      无效。

      为避免这种情况,您必须检查是否匹配。

      除了一般的正则表达式是

       #  "(?<![-.\\d])(?=[-.\\d]*\\d)(-?\\d*)(\\.\\d*)?(?![-.\\d])"
      
       (?<! [-.\d] )       # Lookbehind, not these chars in behind
                           # This won't match like  -'-3.44'
                           # Remove if not needed
      
       (?= [-.\d]* \d )    # Lookahead, subject has to contain a digit
      
                           # Here, all the parts of a valid number are
                           # in front, now just define an arbitrary form 
                           # to pick them out.
                           # Note - the form is all optional, let the engine
                           # choose what to match.
                           # -----------------  
      
       ( -? \d* )          # (1), Required group before decimal, can be empty
       ( \. \d* )?         # (2), Optional group, can be null
                           #      change to (\.\d*) if decimal required
      
       (?! [-.\d] )        # Lookahead, not these chars in front
                           # This won't match like  '3.44'.66
                           # Remove if not needed
      

      示例输出:

       **  Grp 0 -  ( pos 9 , len 8 ) 
      -002.050  
       **  Grp 1 -  ( pos 9 , len 4 ) 
      -002  
       **  Grp 2 -  ( pos 13 , len 4 ) 
      .050  
      
      -----------------
      
       **  Grp 0 -  ( pos 28 , len 3 ) 
      .65  
       **  Grp 1 -  ( pos 28 , len 0 )  EMPTY 
       **  Grp 2 -  ( pos 28 , len 3 ) 
      .65  
      
      -----------------
      
       **  Grp 0 -  ( pos 33 , len 4 ) 
      1.00  
       **  Grp 1 -  ( pos 33 , len 1 ) 
      1  
       **  Grp 2 -  ( pos 34 , len 3 ) 
      .00  
      
      -----------------
      
       **  Grp 0 -  ( pos 39 , len 4 ) 
      9999  
       **  Grp 1 -  ( pos 39 , len 4 ) 
      9999  
       **  Grp 2 -  NULL 
      
      -----------------
      
       **  Grp 0 -  ( pos 104 , len 4 ) 
      -99.  
       **  Grp 1 -  ( pos 104 , len 3 ) 
      -99  
       **  Grp 2 -  ( pos 107 , len 1 ) 
      .  
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-08-25
        • 2010-10-14
        • 2020-09-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多