我正在编写一个旨在采用这样的文本的函数:
%%HEADER
foo bar baz
%%BODY
foo baz baz
并返回一个这样的数组:
{"foo bar baz", "foo baz baz"}
考虑到这一点,我写了以下内容:
string[2] separate_header_body(string input) {
string[2] separated;
auto header = matchFirst(input, regex(r"%%HEADER\n((.|\n)*)\n%%BODY", "g"));
if (header.empty()) {
throw new ParserException("No %%HEADER found.");
} else {
separated[0] = header.front();
auto bdy = matchFirst(input, regex(r"%%BODY\n((.|\n)*)", "g"));
if (bdy.empty()) {
throw new ParserException("No %%BODY found.");
} else {
separated[1] = bdy.front();
}
}
return separated;
}
但是,当我尝试使用以下输入进行测试时:
"%%HEADER\nfoo bar baz\n%%BODY\nfoo baz baz"
第一次捕获是"%%HEADER\nfoo bar baz\n%%BODY
,这显然太多了。我是否错误地使用了std.regex
来获取我想要的内容?
答案 0 :(得分:2)
您可以使用:
auto m = matchFirst(input, regex(r"%%HEADER\n(.*?)\n%%BODY", "s"));
string header = m.captures[1];
和
auto m = matchFirst(input, regex(r"%%BODY\n(.*)", "s"));
string body = m.captures[1];
s修饰符允许点匹配换行符。
问号?
使*
量词变得懒惰。然后它在"\n%%BODY"
请注意,可以使用以下模式一次性提取两个字段:
auto m = matchFirst(regex(r"%%HEADER\n(.*?)\n%%BODY\n(.*)", "s"));
string header = m.captures[1];
string body = m.captures[2];
if (header.empty()) {
throw new ParserException("No %%HEADER found.");
} else {
separated[0] = header;
}
if (body.empty()) {
throw new ParserException("No %%BODY found.");
} else {
separated[1] = body;
}
您只需要提取两个捕获组。
答案 1 :(得分:2)
捕获组的第一个元素(front
)是完全匹配,从模式的第一个字符到最后一个字符。之后是第一个子匹配,即第一个带括号的部分。
因此,请使用[1]
代替front
。或popFront
完全匹配,以便front
是第一个子匹配。