D中的正则表达式捕获太多

时间:2014-07-24 23:44:22

标签: regex d

我正在编写一个旨在采用这样的文本的函数:

%%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来获取我想要的内容?

2 个答案:

答案 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是第一个子匹配。