繁体   English   中英

std::regex_search 与 std::regex_match

[英]std::regex_search vs std::regex_match

我已经测试(@{[^{}]*})*匹配@{whatever}并且它是正确的( https://regex101.com/ )。 因此,尽管正则表达式的可移植性噩梦,我最终构建了正确的 std::regex :

const char *re_str = "@\\{[^\\{\\}]*\\}"; // @{[^{}]*} with curly braces escaped.

可以使用R"()"简化转义,但这不是问题。 正如我所说,正则表达式有效。 这是一个简单的片段示例,它通过迭代使用regex_search提取模式:

#include <iostream>
#include <string>
#include <regex>

int main () {
  std::string str = "Bye @{foo} ! hi @{bar} !";
  std::smatch matches;
  std::string::const_iterator it( str.cbegin() );

  const char *re_str = "@\\{[^\\{\\}]*\\}"; // @{[^{}]*} with curly braces escaped
  // or: const char *re_str = R"(@\{[^\{\}]*\})";

  try {
    std::regex re(re_str);
    while (std::regex_search(it, str.cend(), matches, re)) {
      std::cout << matches[0] << std::endl;
      it = matches.suffix().first;
    }
  }
  catch (std::exception& e) {
    std::cout << e.what() << std::endl;
    return 1;
  }

  return 0;
}

Output:

g++ regex_search.cc && ./a.out
@{foo}
@{bar}

有用。

好吧,我想知道是否有更好的方法(性能 pov)。 所以,我尝试使用std::regex_match而不是迭代std::regex_search 我为此使用了一个捕获组,只是将先前的正则表达式包含在()*中:

const char *re_str = "(@\\{[^\\{\\}]*\\})*"; // (@{[^{}]*})* with curly braces escaped.

这是来源:

#include <iostream>
#include <string>
#include <regex>

int main () {
  std::string str = "Bye @{foo} ! hi @{bar} !";
  std::smatch matches;
  std::string::const_iterator it( str.cbegin() );

  const char *re_str = "(@\\{[^\\{\\}]*\\})*"; // (@{[^{}]*})* with curly braces escaped.

  try {
    std::regex re(re_str);
    if (std::regex_match(str, matches, re)) {
      for (int k=0; k<matches.size(); k++) std::cout << "[" << k << "]: " << matches.str(k) << std::endl;
    }
  }
  catch (std::exception& e) {
    std::cout << e.what() << std::endl;
    return 1;
  }

  return 0;
}

Output:

g++ regex_match.cc && ./a.out

它的 output 是空的

我想,这不是使用std::regex_match的方法,尽管它应该为捕获的组提取匹配项。 也许这次正则表达式无效(我不知道,因为正如我所说,它是可移植性的噩梦)。

所以,

  1. 使用regex_search是否足够并且值得关注性能?
  2. regex_match是更好的算法还是等效的?
  3. 我的regex_match来源有什么问题?

BRs,提前谢谢你

  • std::regex_search在输入字符串的任何位置搜索模式。
  • std::regex_match检查模式是否匹配整个输入字符串。

您的模式与您的整个字符串不匹配,因此std::regex_match将找不到匹配项。 如果您想匹配整个字符串并提取@{foo} .*?(@{[^{}]*}).*?(@{[^{}]*}).*@{bar}部分。

  1. 使用regex_search是否足够并且值得关注性能?
  2. regex_match是更好的算法还是等效的?

我不会说在首先比较这两个功能时应该考虑性能。 每个都有或多或少的特定应用领域:当您迭代地将特定模式匹配为输入的子字符串时使用regex_search ,当您需要整个输入以匹配所述模式时使用regex_match

当输入是任意长度并且在实例化std::regex时未知或者如果捕获输入的所有部分所需的模式过于复杂,我会选择regex_search ,否则我会选择regex_match (如果需要子字符串是通过捕获组获取的)。

  1. 我的regex_match来源有什么问题?

正如其他人已经说过的,它需要匹配整个字符串。 对于您的特定字符串,模式需要看起来像这样:

std::regex re(R"(.*?(@\{[^{}]*\}).*?(@\{[^{}]*\}).*)");

我认为它不像您期望的那样灵活,因此您最好选择已经实现的regex_search选项。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM