c++正则表达式 日期格式匹配

std::regex reg("(\\d{4})-(0\\d{1}|1[0-2])-(0\\d{1}|[12]\\d{1}|3[01])\\s(0\\d{1}|1\\d{1}|2[0-3]):[0-5]\\d{1}:([0-5]\\d{1})");
bool ff = regex_match("2015-03-05 12:08:20", reg);//ff=true

1. 介绍

正则表达式(Regular Expression,常简写为regex、regexp或RE)。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。C++11开始支持正则表达式。
正则表达式非常强大,具体的实现算法有差异,所以会有多种实现方式。C++11支持6种正则表达式引擎。ECMAScript 是其中支持最多元素的引擎,也是regex默认支持的引擎。

  • ECMAScript
  • basic(POSIX Basic Regular Expressions)
  • extended(POSIX Extended Regular Expressions )
  • awk(POSIX awk)
  • grep(POSIX grep )
  • egrep(POSIX grep –E)

2. 正则表达式语法

正则表达式主要两部分构成,特殊字符和普通字符。

  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”:匹配字母或数字或下划线,任意一个字母或数字或下划线,即AZ,az,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属性从结果”匹配”集合中检索捕获的匹配;"$0"表示整个匹配,"$1"表示第1个子表达式的匹配结果。当只有一个子表达式时两者可能是相同。

  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";

3. 正则表达式的使用

目标序列(Target sequence)。为模式而搜索到的字符序列。这可以是二个迭代器所指定的范围、空终止字符串或一个 std::string 。
模式(Pattern)。这是正则表达式自身。它确定构成匹配者。它是从带特定语法的字符串构成的 std::basic_regex 类型对象。受支持的语法变体的描述见 syntax_option_type 。
匹配的数组(Matched array)。关于匹配的信息可作为 std::match_results 类型对象获取。
替换字符串(Replacement string)。这是确定如何替换匹配的字符串,受支持的语法变体的描述不同而不同。

#include <regex> 	// Must be included
#include <string>
#include <iostream>
using namespace std;


int main(int argc, char* argv[])
{
	// .通配符,几个代表几个字符
	std::string strSrc = "Simple";
	std::regex rePattern1("Simpl.");
	cout << boolalpha << std::regex_match(strSrc, rePattern1) << endl;  // true
	std::regex rePattern2("Simp..");
	cout << boolalpha << std::regex_match(strSrc, rePattern2) << endl;  // true

																		// ^在regex_match中的作用无法体现,因为regex_match就要求必须从开始匹配
	std::regex rePattern3(".impl.");
	cout << boolalpha << std::regex_match(strSrc, rePattern3) << endl; // true
	std::regex rePattern4("^.impl.");
	cout << boolalpha << std::regex_match(strSrc, rePattern4) << endl; // true

																	   // regex_match可以用作单纯的匹配判断,也可以匹配获得具体的结果
																	   // 匹配的结果存放在smatch中.smatch中0索引存放完整匹配的结果,1存放第1个()匹配的结果
																	   // 从smatch中取元素,既可以用[],也可以用str(idx)
	std::smatch matchRes1;
	strSrc = "foot.txt";
	std::regex rePattern5("(foot)\\.txt"); // \\.使用转义字符
	cout << boolalpha << std::regex_match(strSrc, matchRes1, rePattern5) << endl; // true
	cout << matchRes1[0] << ":" << matchRes1[1] << endl; // foot.txt:foot
	std::regex rePattern6("(....)\\.txt"); // \\.使用转义字符
	cout << boolalpha << std::regex_match(strSrc, matchRes1, rePattern6) << endl; // true
	cout << matchRes1[0] << ":" << matchRes1[1] << endl; // foot.txt:foot
	cout << matchRes1[0] << ":" << matchRes1.str(1) << endl; // foot.txt:foot
	std::ssub_match ssMatch = matchRes1[1];
	// ssMatch支持强制转换成string类型,和ssMatch.str()等价
	cout << matchRes1[0] << ":" << ssMatch << endl; // foot.txt:foot
	cout << matchRes1[0] << ":" << ssMatch.str() << endl; // foot.txt:foot

														  // *表示匹配前面的o,0或多个均可。即strSrc为ft.txt,fot.txt,foot.txt均匹配成功
	std::regex rePattern7("fo*t\\.txt"); // \\.使用转义字符
	cout << boolalpha << std::regex_match(strSrc, matchRes1, rePattern7) << endl; // true

																				  // +表示匹配前面的o,1或多个均可。即strSrc为fot.txt,foot.txt均匹配成功,ft.txt匹配不成功
	std::regex rePattern8("fo+t\\.txt"); // \\.使用转义字符
	cout << boolalpha << std::regex_match(strSrc, matchRes1, rePattern8) << endl; // true

																				  // ?表示匹配前面的o,0或1个均可。即strSrc为ft.txt,fot.txt均匹配成功,foot.txt匹配不成功
	std::regex rePattern9("fo?t\\.(txt)"); // \\.使用转义字符
	cout << boolalpha << std::regex_match(strSrc, matchRes1, rePattern9) << endl; // false

																				  // 下面有两个括号,即对应两个匹配元素[1],[2]
	std::regex rePattern10("(foo?t)\\.(txt)"); // \\.使用转义字符
	cout << boolalpha << std::regex_match(strSrc, matchRes1, rePattern10) << endl; // true
	cout << matchRes1[0] << ":" << matchRes1.str(1) << ":" << matchRes1[2] << endl; // foot.txt:foot:txt

																					// (ab)是子表达式,(ab)+表示匹配1个或多个ab.
	strSrc = "abab.txt";
	std::regex rePattern11("(ab)+\\.(txt)"); // 可匹配ab.txt,abab.txt,ababab.txt等
	cout << boolalpha << std::regex_match(strSrc, matchRes1, rePattern11) << endl; // true
	cout << matchRes1[0] << ":" << matchRes1.str(1) << ":" << matchRes1[2] << endl;      // abab.txt:ab:txt

																						 // (ab|cd)是子表达式,(ab|cd)+表示匹配1个或多个ab或cd.
	strSrc = "abcdab.txt";
	std::regex rePattern12("(ab|cd)+\\.(txt)"); // 可匹配ab.txt,cd.txt,abcde.txt等
	cout << boolalpha << std::regex_match(strSrc, matchRes1, rePattern12) << endl; // true
	cout << matchRes1[0] << ":" << matchRes1.str(1) << ":" << matchRes1.str(2) << endl;  // abcdab.txt:ab:txt

																						 // {n}表示匹配前面的字符或子表达式n次
	strSrc = "abab.txt";
	std::regex rePattern13("(ab){2}\\.(txt)"); // 只匹配abab.txt等
	cout << boolalpha << std::regex_match(strSrc, matchRes1, rePattern13) << endl; // true
	cout << matchRes1[0] << ":" << matchRes1.str(1) << ":" << matchRes1.str(2) << endl;  // abab.txt:ab:txt

																						 // [abc]表示匹配字符集中的字符
	strSrc = "abcd.txt";
	std::regex rePattern14("[abc]\\.(txt)"); // 只匹配a.txt,b.txt,c.txt
	cout << boolalpha << std::regex_match(strSrc, matchRes1, rePattern14) << endl; // flase

																				   // [abc]+表示匹配1个或多个字符集中的字符
	std::regex rePattern15("[abcde]+\\.(txt)"); // 只要.txt之前的字符属于字符集均匹配
	cout << boolalpha << std::regex_match(strSrc, matchRes1, rePattern15) << endl; // true
	cout << matchRes1[0] << ":" << matchRes1.str(1) << endl;  // abcd.txt:txt

															  // 组([^aBcD]+)匹配到a即停止.[^aBcD]表示匹配非集合中的字符,[^A-Z]表示匹配A-Z之外的字符
	strSrc = "AbCdA23ab4.txt";
	std::regex rePattern16("([^aBcD]+)[^A-Z]+\\.(txt)"); // 只要.txt之前的字符属于字符集均匹配
	cout << boolalpha << std::regex_match(strSrc, matchRes1, rePattern16) << endl; // true
	cout << matchRes1[0] << ":" << matchRes1.str(1) << endl;  // AbCdA23ab4.txt:AbCdA23

															  // [a-zA-Z0-9]{1,20},字符集内的字符,最少1次,最多20次.用来控制数字或字母的个数
	strSrc = "AbCdA23ab4t";
	std::regex rePattern17("[a-zA-Z0-9]{1,20}");
	cout << boolalpha << std::regex_match(strSrc, rePattern17) << endl; // true

																		// regex对象默认是大小写敏感的,regex::icase即指定大小写不敏感
	cout << boolalpha << regex_match("aaaAAA", regex("a*", regex::icase)) << endl;	 // true
	cout << boolalpha << regex_match("aaaAAA", regex("a*")) << endl;				 // false

	return 0;
}

参考:C++11的正则表达式基本用法
参考:
参考:

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

落花逐流水

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值