c11-regex正则表达式简述

9次阅读

共计 2393 个字符,预计需要花费 6 分钟才能阅读完成。

regex 库中涉及到的主要类型有:

  • 以 std::string 为代表的处理字符串的类型(我们知道还有存储 wchar_t 的 wstring 类、原生 c 式字符串 const char* 等等,为了简化处理仅介绍 std::string 类型相关的操作,当你把握住了 regex 的主脉络之后,想使用其他的版本只要类比就可以)
  • std::regex 类,该类型需要一个代表正则表达式的字符串和一个文法选项作为输入,当文法选项不提供时默认为 ECMAScript。
  • std::match_results 类,该类用来记录匹配的结果,这是一个模板类,该类的模板参数是一个迭代器类型,对于 std::string 来说我们定义了 smatch 作为 match_results<string::const_iterator> 作为别名。
  • std::sub_match 类,该类其实封装了两个迭代器,第一个代表开始部分,第二个代表结束部分,就像你用两个下表索引去表达一个字符串的某一个子串一样。这个类就是通过这样的方式提供原字符串的某一个子串作为结果。实际上 match_results 中就封装了一些 std::sub_match 类型的对象。(为什么是一些而不是一个,因为一次匹配可能会产生多个结果返回,regex 认为每个括号对构成一个子匹配项,regex 匹配的结果可以显式每个子匹配项匹配到的内容。)
  • 现在我们有了表达字符串的类,表达正则匹配的类,表达匹配结果的类,接下来 regex 提供三个匹配函数:
bool std::regex_match(...)
bool std::regex_search(...)
string std::regex_replace(...)// 实际上返回类型是根据你输入的数据类型对应的 basic_string 类。

首先说明三个函数功能上的不同,std::regex_match 是全文匹配,即它希望你输入的字符串要和正则表达式全部匹配,才认为匹配成功,否则匹配失败,而 std::regex_search 是在你输入的字符串中不断搜索符合正则表达式描述的子字符串,然后将第一个匹配到的子字符串返回。std::regex_replace 是在 std::regex_search 的基础上更进一步,可以将匹配的子字符串替换为你提供的字符串。

看几个例子:

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

int main() {std::regex pattern("\\d{4}");
  std::string content("hello_2018");
  std::smatch result;
  if (std::regex_match(content, result, pattern)) {std::cout << result[0];
  }
  system("pause");
  return 0;
}

匹配失败,什么都不会输出。
这里说明一下为什么输出的是 result[0],其实 result[0] 返回的就是一个 sub_match 类型的对象。regex 中认为正则表达式的每个括号对构成一个子匹配项,并认为整个字符串作为 0 号子匹配项,然后根据左括号出现的位置,从 1 号开始编号,因此返回的 result[0] 就是匹配整个正则表达式的字符串。

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

int main() {std::regex pattern("\\d{4}");
  std::string content("hello_2018 by_2017");
  std::smatch result;
  if (std::regex_search(content, result, pattern)) {std::cout << result[0];
  }
  system("pause");
  return 0;
}

搜索到第一个符合正则表达式的子串,输入 2018。

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

int main() {std::regex pattern("\\d{4}");
  std::string content("hello_2018 by_2017");
  std::smatch result;

  auto begin = content.cbegin();
  auto end = content.cend();
  while (std::regex_search(begin, end, result, pattern)) {std::cout << result[0] << " ";
    begin = result[0].second;
  }
  system("pause");
  return 0;
}

用上述方式可以输出字符串中所有符合正则表达式匹配要求的字符串,输入 2018 2017。

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

int main() {std::regex pattern("\\d{4}");
  std::string content("hello_2018 by_2017");

  std::string result = std::regex_replace(content, pattern, "everyone");
  std::cout << result;
  system("pause");
  return 0;
}

输出 hello_everyone by_everyone。

以上就是 c ++11 提供的 regex 模块的主要脉络,其余的关于对 const char*、wcahr_t 类型的支持,以及 regex_iterator、regex_token_iterator 等迭代器的使用,以及掌控正则表达式行为方式的 syntax_option_type 的详细内容,等你需要去了解的时候去看官网的详解,相信学起来并不难。

正文完
 0