正则表达式Regex(regular expression)是一种强大的描述字符序列的工具。在许多语言中都存在着正则表达式,C++11中也将正则表达式纳入了新标准的一部分,不仅如此,它还支持了6种不同的正则表达式的语法,分别是:ECMASCRIPT、basic、extended、awk、grep和egrep。其中ECMASCRIPT是默认的语法,具体使用哪种语法我们可以在构造正则表达式的时候指定。

正则表达式是一种文本模式。正则表达式是强大、便捷、高效的文本处理工具。正则表达式本身,加上如同一门袖珍编程语言的通用模式表示法(general pattern notation),赋予使用者描述和分析文本的能力。配合上特定工具提供的额外支持,正则表达式能够添加、删除、分离、叠加、插入和修整各种类型的文本和数据。

完整的正则表达式由两种字符构成:特殊字符(special characters)称为”元字符”(meta characters),其它为”文字”(literal),或者是普通文本字符(normal text characters,如字母、数字、汉字、下划线)。正则表达式的元字符提供了更强大的描述能力。

和文本编辑器一样,绝大多数高级编程语言均支持正则表达式,如Perl、Java、Python、C/C++,这些语言都有各自的正则表达式包。

一个正则表达式仅仅为一个字符串,它没有长度限制。“子表达式”指的是整个正则表达式中的一部分,通常是括号内的表达式,或者是由”|”分割的多选分支。

默认情况下,表达式中的字母是要区分大小写的。

常用的元字符:

1.      “.”: 匹配除"\n"之外的任何单个字符,若要匹配包括"\n"在内的任意字符,需使用诸如"[\s\S]"之类的模式;

2.       “^”:匹配输入字符串的开始位置,不匹配任何字符,要匹配”^”字符本身,需使用”\^”;

3.      “$”:匹配输入字符串结尾的位置,不匹配任何字符,要匹配”$”字符本身,需使用”\$”;

4.      “*”: 零次或多次匹配前面的字符或子表达式,”*”等效于”{0,}”,如”\^*b”可以匹配”b”、”^b”、”^^b”、…;

5.      “+”: 一次或多次匹配前面的字符或子表达式,等效于”{1,}”,如”a+b”可以匹配”ab”、”aab”、”aaab”、…;

6.      “?”: 零次或一次匹配前面的字符或子表达式,等效于”{0,1}”,如”a[cd]?”可以匹配”a”、”ac”、”ad”; 当此字符紧随任何其他限定符”*”、”+”、”?”、”{n}”、”{n,}”、”{n,m}”之后时,匹配模式是"非贪心的"。"非贪心的"模式匹配搜索到的、尽可能短的字符串,而默认的"贪心的"模式匹配搜索到的、尽可能长的字符串。如,在字符串"oooo"中,"o+?"只匹配单个"o",而"o+"匹配所有"o";

7.      “|”:将两个匹配条件进行逻辑"或"(Or)运算,如正则表达式”(him|her)”匹配"itbelongs to him"和"it belongs to her",但是不能匹配"itbelongs to them.";

8.      “\”: 将下一字符标记为特殊字符、文本、反向引用或八进制转义符,如,”n”匹配字符”n”,”\n”匹配换行符,序列”\\”匹配”\”,”\(“匹配”(“;

9.      “\w”:匹配字母或数字或下划线,任意一个字母或数字或下划线,即A~Z,a~z,0~9,_中任意一个;

10.  “\W”:匹配任意不是字母、数字、下划线的字符;

11.  “\s”:匹配任意的空白符,包括空格、制表符、换页符等空白字符的其中任意一个,与”[ \f\n\r\t\v]”等效;

12.  “\S”:匹配任意不是空白符的字符,与”[^\f\n\r\t\v]”等效;

13.  “\d”:匹配数字,任意一个数字,0~9中的任意一个,等效于”[0-9]”;

14.  “\D”:匹配任意非数字的字符,等效于”[^0-9]”;

15.  “\b”: 匹配一个字边界,即字与空格间的位置,也就是单词和空格之间的位置,不匹配任何字符,如,"er\b"匹配"never"中的"er",但不匹配"verb"中的"er";

16.  “\B”: 非字边界匹配,"er\B"匹配"verb"中的"er",但不匹配"never"中的"er";

17.  “\f”:匹配一个换页符,等价于”\x0c”和”\cL”;

18.  “\n”:匹配一个换行符,等价于”\x0a”和”\cJ”;

19.  “\r”:匹配一个回车符,等价于”\x0d”和”\cM”;

20.  “\t”:匹配一个制表符,等价于”\x09”和”\cI”;

21.  “\v”:匹配一个垂直制表符,等价于”\x0b”和”\cK”;

22.  “\cx”:匹配”x”指示的控制字符,如,\cM匹配Control-M或回车符,”x”的值必须在”A-Z”或”a-z”之间,如果不是这样,则假定c就是"c"字符本身;

23.  “{n}”:”n”是非负整数,正好匹配n次,如,"o{2}"与"Bob"中的"o"不匹配,但与"food"中的两个"o"匹配;

24.  “{n,}”:”n”是非负整数,至少匹配n次,如,"o{2,}"不匹配"Bob"中的"o",而匹配"foooood"中的所有”o”,"o{1,}"等效于"o+","o{0,}"等效于"o*";

25.  “{n,m}”:”n”和”m”是非负整数,其中n<=m,匹配至少n次,至多m次,如,"o{1,3}"匹配"fooooood"中的头三个o,'o{0,1}'等效于'o?',注意,不能将空格插入逗号和数字之间;如”ba{1,3}”可以匹配”ba”或”baa”或”baaa”;

26.  “x|y”:匹配”x”或”y”,如,”z|food”匹配"z"或"food";”(z|f)ood”匹配"zood"或"food";

27.  “[xyz]”:字符集,匹配包含的任一字符,如,"[abc]"匹配"plain"中的"a";

28.  “[^xyz]”:反向字符集,匹配未包含的任何字符,匹配除了”xyz”以外的任意字符,如,"[^abc]"匹配"plain"中的"p";

29.  “[a-z]”:字符范围,匹配指定范围内的任何字符,如,"[a-z]"匹配"a"到"z"范围内的任何小写字母;

30.  “[^a-z]”:反向范围字符,匹配不在指定的范围内的任何字符,如,"[^a-z]"匹配任何不在"a"到"z"范围内的任何字符;

31.  “( )”:将”(“和”)”之间的表达式定义为”组”group,并且将匹配这个表达式的字符保存到一个临时区域,一个正则表达式中最多可以保存9个,它们可以用”\1”到”\9”的符号来引用;

32.  “(pattern)”:匹配pattern并捕获该匹配的子表达式,可以使用$0…$9属性从结果”匹配”集合中检索捕获的匹配;

33.  “(?:pattern)”:匹配pattern但不捕获该匹配的子表达式,即它是一个非捕获匹配,不存储供以后使用的匹配,这对于用”or”字符” (|)”组合模式部件的情况很有用, 如,”industr(?:y|ies)”是比”industry|industries”更简略的表达式;

34.  “(?=pattern)”: 非获取匹配,正向肯定预查,在任何匹配pattern的字符串开始处匹配查找字符串,该匹配不需要获取供以后使用。如,"Windows(?=95|98|NT|2000)"能匹配"Windows2000"中的"Windows",但不能匹配"Windows3.1"中的"Windows"。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始;

35.  “(?!pattern)”: 非获取匹配,正向否定预查,在任何不匹配pattern的字符串开始处匹配查找字符串,该匹配不需要获取供以后使用。如"Windows(?!95|98|NT|2000)"能匹配"Windows3.1"中的"Windows",但不能匹配"Windows2000"中的"Windows";

要匹配某些特殊字符,需在此特殊字符前面加上”\”,如要匹配字符”^”、”$”、”()”、”[]”、”{}”、”.”、”?”、”+”、”*”、”|”,需使用” \^”、” \$”、” \ (“、”\)”、” \ [“、”\]”、” \{“、”\}”、” \.”、” \?”、” \+”、” \*”、” \|”。

在C++/C++11中,GCC版本是4.9.0及以上,VS版本为VS2013及以上时,会有regex头文件,此头文件中会有regex_match、regex_search、regex_replace等函数可供调用,以下是测试代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include "regex.hpp"
#include <regex>
#include <string>
#include <vector>
#include <iostream>
int test_regex_match()
{
 std::string pattern{ "\\d{3}-\\d{8}|\\d{4}-\\d{7}" }; // fixed telephone
 std::regex re(pattern);
 std::vector<std::string> str{ "010-12345678", "0319-9876543", "021-123456789"};
 /* std::regex_match:
  判断一个正则表达式(参数re)是否匹配整个字符序列str,它主要用于验证文本
  注意,这个正则表达式必须匹配被分析串的全部,否则返回false;如果整个序列被成功匹配,返回true
 */
 for (auto tmp : str) {
  bool ret = std::regex_match(tmp, re);
  if (ret) fprintf(stderr, "%s, can match\n", tmp.c_str());
  else fprintf(stderr, "%s, can not match\n", tmp.c_str());
 }
 return 0;
}
int test_regex_search()
{
 std::string pattern{ "http|hppts://\\w*$" }; // url
 std::regex re(pattern);
 /* std::regex_search:
  类似于regex_match,但它不要求整个字符序列完全匹配
  可以用regex_search来查找输入中的一个子序列,该子序列匹配正则表达式re
 */
 for (auto tmp : str) {
  bool ret = std::regex_search(tmp, re);
  if (ret) fprintf(stderr, "%s, can search\n", tmp.c_str());
  else fprintf(stderr, "%s, can not search\n", tmp.c_str());
 }
 return 0;
}
int test_regex_search2()
{
 std::string pattern{ "[a-zA-z]+://[^\\s]*" }; // url
 std::regex re(pattern);
 std::string str{ "my csdn blog addr is: http://blog.csdn.net/fengbingchun , my github addr is: https://github.com/fengbingchun " };
 std::smatch results;
 while (std::regex_search(str, results, re)) {
  for (auto x : results)
   std::cout << x << " ";
  std::cout << std::endl;
  str = results.suffix().str();
 }
 return 0;
}
int test_regex_replace()
{
 std::string pattern{ "\\d{18}|\\d{17}X" }; // id card
 std::regex re(pattern);
 std::vector<std::string> str{ "123456789012345678", "abcd123456789012345678efgh",
  "abcdefbg", "12345678901234567X" };
 std::string fmt{ "********" };
 /* std::regex_replace:
  在整个字符序列中查找正则表达式re的所有匹配
  这个算法每次成功匹配后,就根据参数fmt对匹配字符串进行替换
 */
 for (auto tmp : str) {
  std::string ret = std::regex_replace(tmp, re, fmt);
  fprintf(stderr, "src: %s, dst: %s\n", tmp.c_str(), ret.c_str());
 }
 return 0;
}
int test_regex_replace2()
{
 std::string s("there is a subsequence in the string\n");
 std::regex e("\\b(sub)([^ ]*)"); // matches words beginning by "sub"
 // using string/c-string (3) version:
 std::cout << std::regex_replace(s, e, "sub-$2");
 // using range/c-string (6) version:
 std::string result;
 std::regex_replace(std::back_inserter(result), s.begin(), s.end(), e, "$2");
 std::cout << result;
 // with flags:
 std::cout << std::regex_replace(s, e, "$1 and $2", std::regex_constants::format_no_copy);
 std::cout << std::endl;
 return 0;
}

GitHub:https://github.com/fengbingchun/Messy_Test

以上所述是小编给大家介绍的正则表达式简介及在C++11中的简单使用教程,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

【转】正则表达式简介及在C++11中的简单使用教程的更多相关文章

  1. 正则表达式简介及在C++11中的简单使用

    正则表达式(regular expression)是计算机科学中的一个概念,又称规则表达式,通常简写为regex.regexp.RE.regexps.regexes.regexen. 正则表达式是一种 ...

  2. IOS中的Block与C++11中的lambda

    ios中的block 可以说是一种函数指针,但更确切的讲,其实际上其应该算是object-c对C++11中lambda的支持或者说是一个语言上的变体,其实际内容是一样的,C++的lambda我已经有简 ...

  3. php正则表达式简介

    正则表达式简介 正则表达式Regular Expression,使用单个字符串来描述.匹配一系列符合某个句法规则的字符串.代表性书籍<正则表达式之道>里面有详细论述,本书籍为个人查阅之用力 ...

  4. 1000行代码徒手写正则表达式引擎【1】--JAVA中正则表达式的使用

    简介: 本文是系列博客的第一篇,主要讲解和分析正则表达式规则以及JAVA中原生正则表达式引擎的使用.在后续的文章中会涉及基于NFA的正则表达式引擎内部的工作原理,并在此基础上用1000行左右的JAVA ...

  5. C++11 中值得关注的几大变化(网摘)

    C++11 中值得关注的几大变化(详解) 原文出处:[陈皓 coolshell] 源文章来自前C++标准委员会的 Danny Kalev 的 The Biggest Changes in C++11 ...

  6. PERL 正则表达式简介

    来源:脚本之家 网址:http://www.jb51.net/article/17429.htm 一.简介 二.匹配操作符 三.模式中的特殊字符 1.字符+ 2.字符 []和[^] 3.字符 *和? ...

  7. MySql 正则表达式简介及使用

    MySql正则表达式简介及使用 by:授客 QQ:1033553122 简介 正则表达式描述了一组字符串,该字符放置于REGEXP工具后面.作用是将一个正则表达式与一个文本串进行比较. 最简单的正则表 ...

  8. C++11 中值得关注的几大变化(详解)

    源文章来自前C++标准委员会的 Danny Kalev 的 The Biggest Changes in C++11 (and Why You Should Care),赖勇浩做了一个中文翻译在这里. ...

  9. C++11中的raw string literals

    作为一名C++书看得少得可怜的新手,我一直没有勇气去系统地学习一下C++ 11添加的新特性.不过,平日里逛论坛,阅读大犇们的博客,倒是了解了一些.比如,这个帖子: 如何绕过g++ 4.8.1那个不能在 ...

随机推荐

  1. 每天一个linux命令(性能、优化):【转载】vmstat命令

    vmstat是Virtual Meomory Statistics(虚拟内存统计)的缩写,可对操作系统的虚拟内存.进程.CPU活动进行监控.他是对系统的整体情况进行统计,不足之处是无法对某个进程进行深 ...

  2. bzoj 5334 数学计算

    bzoj 5334 数学计算 开始想直接模拟过程做,但模数 \(M\) 不一定为质数,若没有逆元就 \(fAKe\) 掉了. 注意到操作 \(2\) 是删除对应的操作 \(1\) ,相当于只有 \(1 ...

  3. HTTP Client Performance Improvements

    HTTP Client Performance Improvements https://blogs.msdn.microsoft.com/webdev/2018/10/17/asp-net-core ...

  4. Sharepoint Web.config trust level="Full"权限说明

    在SharePoint里面,不仅有用户的权限,还有代码的权限.比如,我们在安装一个自定义的WebPart的时候,默认的情况下是不能操纵文件夹的,如果你看一些教你怎么做WebPart的文章的话,你会发现 ...

  5. Ubuntu下环境变量设置

    [内容来自网络] 相应配置文件介绍: 1) /etc/profile :在登录时,操作系统定制用户环境使用的第一个文件,此文件为系统的每个用户设置环境信息,当用户第一次登录时,改文件被执行 2) /e ...

  6. http请求发生了两次(options请求)

    前言 自后台restful接口流行开来,请求了两次的情况(options请求)越来越普遍.笔者也在实际的项目中遇到过这种情况,做一下整理总结. 文章书写思路: 为什么发生两次请求 http的请求方式, ...

  7. SharePoint无法搜索解决

    重启服务器后,站点搜索时提示错误,无法进行搜索,进入管理中心搜索管理看到,"查询处理"出错. 解决方法: 停止搜索服务,重新启动,如下图所示 重启服务后,过了几分钟重新查询,查询正 ...

  8. redis+php实现微博功能(二)

    数据结构: set post:postid:3:time timestampset post:postid:3:userid 5 set post:postid:3:content 测试发布哈哈哈哈 ...

  9. nginx和php-fpm通信的两种方式 unix socket和TCP

    nginx和fastcgi的通信方式有两种,一种是TCP 一种是unix socket TCP使用的是 127.0.0.1:9000端口,将fastcgi_pass参数修改为127.0.0.1:900 ...

  10. 嵌入ARM硬核的FPGA

    目前,在FPGA上嵌入ARM硬核的包括Xilinx的zynq系列以及Intel 的CYCLONEV系列. Zynq出来有一定市场,但是这个市场不是传统FPGA的主流市场,而是为了和微处理抢一些控制领域 ...