std::regex 不认识 $
std::regex doesn't recognize $
我尝试用正则表达式解析文件的内容:
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 中的正则表达式,它 100% 有效,但在 std::regex regex_search
returns 中是错误的。似乎 $
字符未被识别,posix
语法也未被识别 ^
。我尝试使用 ECMAScript
,并且正则表达式有效,只有当我删除 $
符号时。
//ecmascript syntax
bool result = regex_search(txt.c_str(), m, regex("^#(\S*)"));
文件是使用二进制标志读取的,因此 txt
字符串保留了 $
语法所需的所有 \r\n
个字符。我寻求帮助,如何解决这个问题。
请注意,在大多数情况下,$
锚点仅用作字符串结尾(整个输入)锚点。参见 this thread。您可以使用基于正向预测的自定义边界模式 $
匹配行尾位置,(?=$|\r?\n)
.
另一个问题是您在常规字符串文字中使用了 \S
转义序列。这意味着,它被视为 S
字母,而不是非白色 space 模式。使用原始字符串文字,以便您可以使用单个 \
来定义 regex 转义序列(其中 \
转义 d
、s
, 等应该是文字反斜杠)。或者在常规字符串文字中进行双重转义 \
。
另外,@HWalters 已经注意到 ^#\S+$
不会匹配 #include <stdio.h>
,你需要考虑里面的 space。因此,你的正则表达式可能看起来像 ^#include[ \t]+(\S+)(?=$|\r?\n)
,以确保你有 #include
,然后是一些水平的 spaces,然后捕获任何数字(这里有 1 个或更多,+
) 的非白色space 字符,直到字符串末尾或换行符(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;
}
我尝试用正则表达式解析文件的内容:
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 中的正则表达式,它 100% 有效,但在 std::regex regex_search
returns 中是错误的。似乎 $
字符未被识别,posix
语法也未被识别 ^
。我尝试使用 ECMAScript
,并且正则表达式有效,只有当我删除 $
符号时。
//ecmascript syntax
bool result = regex_search(txt.c_str(), m, regex("^#(\S*)"));
文件是使用二进制标志读取的,因此 txt
字符串保留了 $
语法所需的所有 \r\n
个字符。我寻求帮助,如何解决这个问题。
请注意,在大多数情况下,$
锚点仅用作字符串结尾(整个输入)锚点。参见 this thread。您可以使用基于正向预测的自定义边界模式 $
匹配行尾位置,(?=$|\r?\n)
.
另一个问题是您在常规字符串文字中使用了 \S
转义序列。这意味着,它被视为 S
字母,而不是非白色 space 模式。使用原始字符串文字,以便您可以使用单个 \
来定义 regex 转义序列(其中 \
转义 d
、s
, 等应该是文字反斜杠)。或者在常规字符串文字中进行双重转义 \
。
另外,@HWalters 已经注意到 ^#\S+$
不会匹配 #include <stdio.h>
,你需要考虑里面的 space。因此,你的正则表达式可能看起来像 ^#include[ \t]+(\S+)(?=$|\r?\n)
,以确保你有 #include
,然后是一些水平的 spaces,然后捕获任何数字(这里有 1 个或更多,+
) 的非白色space 字符,直到字符串末尾或换行符(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;
}