std :: regex无法识别$

时间:2017-09-06 03:09:33

标签: c++ regex stl posix

我尝试使用正则表达式解析文件的内容:

ifstream file_stream("commented.cpp",ifstream::binary);

std::string txt((std::istreambuf_iterator<char>(file_stream)),
std::istreambuf_iterator<char>());

cmatch m;
bool result = regex_search(txt.c_str(), m, regex("^#(\S*)$",regex_constants::basic));

该文件是c源,它以行开头:

#include <stdio.h>

我试图解析一个指令,我检查了regexbuddy中的regexp并且它100%工作,但是在std :: regex regex_search中返回false。似乎$字符未被识别,^语法也posix。我尝试使用ECMAScript,只有删除$符号才能使用正则表达式。

//ecmascript syntax
bool result = regex_search(txt.c_str(), m, regex("^#(\S*)"));

使用二进制标志读取文件,因此txt字符串保留\r\n语法所需的所有$个字符。我寻求帮助,如何解决这个问题。

1 个答案:

答案 0 :(得分:1)

请注意,$锚点在大多数情况下仅用作字符串结尾(整个输入)锚点。见this thread。您可以使用基于正前瞻$的自定义边界模式,使(?=$|\r?\n)匹配行位置的结尾。

另一个问题是您在常规字符串文字中使用\S转义序列。这意味着,它被视为S字母,而不是非空格模式。使用原始字符串文字,以便您可以使用单个\来定义正则表达式转义序列(其中\转义ds,等应该是字面反斜杠)。或者在常规字符串文字中双重转义\

此外,@ HWalters已经注意到^#\S+$#include <stdio.h>不匹配,您需要考虑内部空间。因此,您的正则表达式可能看起来像^#include[ \t]+(\S+)(?=$|\r?\n),以确保您拥有#include,然后是一些水平空格,然后捕获任何数字(此处为1或更多,带有+)非whitespace chars一直到字符串结尾或换行符(CRLF或LF)。

这是一个snippet

regex r(R"(^#include[ \t]+(\S+)(?=$|\r?\n))");
string s("#include <stdio.h>\r\n#include <regex>");
smatch m;
if (regex_search(s, m, r)) {
    std::cout << m[1] << std::endl;
}