正则表达式无法从字符串中提取双参数子字符串

时间:2014-11-04 15:33:29

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

我正在尝试使用Regex库工具从文本文件中提取double和integer参数。这是一个捕获我一直得到的'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库并不熟悉,也找不到任何立即有用的东西。知道导致此错误消息的原因吗?为了编译我的代码,我使用g ++并启用-std = c ++ 11。但是,我确信问题不是由the answers given to this earlier question中建议的我的g ++编译器引起的(我试过several g++ compilers here)。

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

在抛出'std :: regex_error'的实例后终止调用 what():regex_error 中止

3 个答案:

答案 0 :(得分:3)

假设您有gcc4.9(旧版本不附带支持<regex>的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]+))");

以上内容将匹配单个,可选的主导+-符号。

答案 1 :(得分:0)

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

试试这个:

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

答案 2 :(得分:0)

我认为您收到错误是因为smatch对象中的what 无效。

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

除此之外,一般正则表达式

 #  "(?<![-.\\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 ) 
.