C++11 正则表达式——实例系统(转载)
一.用正则表达式判断邮箱格式是否正确
1 #include <regex> #include <iostream> #include <string> bool is_email_valid(const std::string& email)
{ const std::regex pattern("(\\w+)(\\.|_)?(\\w*)@(\\w+)(\\.(\\w+))+");
//const std::regex pattern("(\\w+)(\\.|_)?(\\w*)@(\\w+)(\\.|-)?(\\w*)(\\.(\\w+))+");验证最全面 return std::regex_match(email, pattern); } int main() { std::string email1 = "marius.bancila@domain.com"; std::string email2 = "mariusbancila@domain.com"; std::string email3 = "marius_b@domain.co.uk"; std::string email4 = "marius@domain"; std::cout << email1 << " : " << (is_email_valid(email1) ? "valid" : "invalid") << std::endl; std::cout << email2 << " : " << (is_email_valid(email2) ? "valid" : "invalid") << std::endl; std::cout << email3 << " : " << (is_email_valid(email3) ? "valid" : "invalid") << std::endl; std::cout << email4 << " : " << (is_email_valid(email4) ? "valid" : "invalid") << std::endl; return ;
}
运行结果
这里对is_email_valid()函数中的正则表达式做一个简短的说明,如果对于正则表示不是很清楚的同学就能很容易理解了。
const std::regex pattern("(\\w+)(\\.|_)?(\\w*)@(\\w+)(\\.(\\w+))+");
首先注意‘()’表示将正则表达式分成子表达式,每个‘()’之间的内容表示一个子表达式;‘\’是一个转义字符,‘\\’表示扔掉第二个‘\’的转义特
性,‘\w+’表示匹配一个或多个单词,‘+’表示重复一次或者多次,因此第一个子表达式的意思就是匹配一个或者多个单词;接着看第二个子表达式,‘|’
表示选择,出现‘.’或者‘_’,后面的‘?’表示该子表示出现一次或者零次,因此第二个子表示表示‘.’或‘_’出现不出现都匹配。第三个子表达式表示
出现一个单词,‘*’表示任意个字符。后面的子表示根据已经介绍的内容,已经可以容易理解,就不再赘述。通过对正则表达式匹配模式串的分析,可以容易理解
运行结果。
下面一个例子通过正则表达式识别和打印IP地址的各个部分:
#include <regex> #include <iostream> #include <string> void show_ip_parts(const std::string& ip) { // regular expression with 4 capture groups defined with // parenthesis (...) const std::regex pattern("(\\d{1,3}):(\\d{1,3}):(\\d{1,3}):(\\d{1,3})"); // object that will contain the sequence of sub-matches std:: match_results<std::string::const_iterator> result; // match the IP address with the regular expression bool valid = std:: regex_match(ip, result, pattern); std::cout << ip << " \t: " << (valid ? "valid" : "invalid") << std::endl; // if the IP address matched the regex, then print the parts if(valid) { std::cout << "b1: " << result[] << std::endl; std::cout << "b2: " << result[] << std::endl; std::cout << "b3: " << result[] << std::endl; std::cout << "b4: " << result[] << std::endl; } } int main()
{ show_ip_parts("1:22:33:444"); show_ip_parts("1:22:33:4444"); show_ip_parts("100:200"); return ; }
运行结果:
是对正则表达式的模式串做一个说明:首先还是通过‘()’将这个串分成几个子表达式,其中\d表示匹配一个数字,{,}表示数字的个数,例如{1,3}可以理解为匹配一个小于1000的数字(1-3位数都符合匹配要求)。
程序中还使用了match_results类,用来保存匹配的每一个子序列。调用regex_match(ip,result,pattern),表示将ip中与模式串pattern匹配的结果放在result中。
result最后可以通过下标来访问各个匹配的子表达式。
#include <regex> #include <iostream> #include <string> int main() { const std::tr1::regex pattern("(\\w+day)"); // the source text std::string weekend = "Saturday and Sunday"; std::smatch result; bool match = std::regex_search(weekend, result, pattern); if(match) { for(size_t i = ; i < result.size(); ++i) { std::cout << result[i] << std::endl; } } std::cout<<std::endl; return ; }
运行结果:
上面这个例子只能返回第一个匹配的项,如果要返回所有匹配的子序列,可以使用下面的方式:
#include <regex> #include <iostream> #include <string> int main() { // regular expression const std::regex pattern("\\w+day"); // the source text std::string weekend = "Saturday and Sunday, but some Fridays also."; const std::sregex_token_iterator end; //需要注意一下这里 for (std::sregex_token_iterator i(weekend.begin(),weekend.end(), pattern); i != end ; ++i) { std::cout << *i << std::endl; } std::cout<<std::endl; return ; }
运行结果:
下面的例子将元音字母打头的单词前面的a替换为an:
#include <regex> #include <iostream> #include <string> int main() { // text to transform std::string text = "This is a element and this a unique ID."; // regular expression with two capture groups const std::regex pattern("(\\ba (a|e|i|u|o))+"); // the pattern for the transformation, using the second // capture group std::string replace = "an $2"; std::string newtext = std::regex_replace(text, pattern, replace); std::cout << newtext << std::endl; std::cout << std::endl; return ; }
运行结果:
还是来说明一下,这里主要使用了regex_replace(text, pattern, replace),意思是将text的内容按照pattern进行匹配,匹配成功的使用replace串进行替换,并将替换后的结果作为函数值返回。需要 注意的是std::string replace = "an $2"; 这里‘$2’表示模式串的第二个子表达式,
也就是以a,e,i,o,u开头的单词。
三.下面一个例子将进行年月日格式的转换,将DD-MM-YYYY –> YYYY-MM-DD,其中‘.’或者‘/’都能正确识别。
#include <regex> #include <iostream> #include <string> std::string format_date(const std::string& date) { // regular expression const std:: regex pattern("(\\d{1,2})(\\.|-|/)(\\d{1,2})(\\.|-|/)(\\d{4})"); // transformation pattern, reverses the position of all capture groups std::string replacer = "$5$4$3$2$1"; // apply the tranformation return std:: regex_replace(date, pattern, replacer); } int main() { std::string date1 = "1/2/2008"; std::string date2 = "12.08.2008"; std::cout << date1 << " -> " << format_date(date1) << std::endl; std::cout << date2 << " -> " << format_date(date2) << std::endl; std::cout << std::endl; return ; }
运行结果:
说明,这个例子也很有实用价值,这里用到的正则表达式的匹配模式前面都已经进行过说明就不在分析。
相信通过以上例子,对正则表达式的运用已经有了一个不错的了解,下面再来添加一个实例,加深一下理解。
下面一个例子用来查找给定文本中new的个数和delete的个数是否相等:
#include <iostream> #include <string> #include <regex> int main() { // "new" and "delete" 出现的次数是否一样? std::regex reg("(new)|(delete)"); std::smatch m; std::string s= "Calls to new must be followed by delete. \ Calling simply new results in a leak!"; int new_counter=; int delete_counter=; std::string::const_iterator it=s.begin(); std::string::const_iterator end=s.end(); while (std::regex_search(it,end,m,reg)) { // 是 new 还是 delete? m[].matched ? ++new_counter : ++delete_counter; it=m[].second; } if (new_counter!=delete_counter) std::cout << "Leak detected!\n"; else std::cout << "Seems ok...\n"; std::cout << std::endl; }
运行结果:
运行结果表明,new和delete的数量不相等,也就是发生了“内存泄露”。
为了帮助理解,上面对于match_results类型的下标操作的意义,请看ISOIEC14882 C++11的说明:
#include <iostream> #include <string> #include <regex> using namespace std; class regex_callback { int sum_; public: regex_callback() : sum_() {} template <typename T> void operator()(const T& what) { sum_+=atoi(what[].str().c_str()); } int sum() const { return sum_; } }; int main() { regex reg("(\\d+),?"); string s="1,1,2,3,5,8,13,21"; sregex_iterator it(s.begin(),s.end(),reg); sregex_iterator end; regex_callback c; int sum=for_each(it,end,c).sum();//for_each返回的是这个函数对象,因此可以调用sum cout<<sum<<endl; cout<<endl; }
运行结果:
#include <iostream> #include <string> #include <regex> using namespace std; int main() { regex reg("/"); vector<std::string> vec; string s="Split/Vulue/Teather/Neusoft/Write/By/Lanwei"; sregex_token_iterator it(s.begin(),s.end(),reg,-);//// -1逆向匹配,就是匹配除了'/'之外的 sregex_token_iterator end ; while(it!=end) vec.push_back(*it++); copy(vec.begin(),vec.end(),ostream_iterator<std::string>( cout,"\n")); }
运行结果:
C++11 正则表达式——实例系统(转载)的更多相关文章
- Java-Runoob-高级教程-实例-方法:11. Java 实例 – enum 和 switch 语句使用
ylbtech-Java-Runoob-高级教程-实例-方法:11. Java 实例 – enum 和 switch 语句使用 1.返回顶部 1. Java 实例 - enum 和 switch 语句 ...
- Java-Runoob-高级教程-实例-数组:11. Java 实例 – 删除数组元素
ylbtech-Java-Runoob-高级教程-实例-数组:11. Java 实例 – 删除数组元素 1.返回顶部 1. Java 实例 - 删除数组元素 Java 实例 以下实例演示了如何使用 ...
- Java-Runoob-高级教程-实例-字符串:11. Java 实例 - 字符串性能比较测试
ylbtech-Java-Runoob-高级教程-实例-字符串:11. Java 实例 - 字符串性能比较测试 1.返回顶部 1. Java 实例 - 字符串性能比较测试 Java 实例 以下实例演 ...
- JavaScript学习11 数组排序实例
JavaScript学习11 数组排序实例 数组声明 关于数组对象的声明,以前说过:http://www.cnblogs.com/mengdd/p/3680649.html 数组声明的一种方式: va ...
- c++11 正则表达式基本使用
c++ 11 正则表达式 常用的方法 regex_match regex_search regex_replace 等. regex_match 要求正则表达式必须与模式串完全匹配,例如: strin ...
- C++11 | 正则表达式(4)
C++11还支持正则表达式里的子表达式(也叫分组),用sub_match这个类就行了. 举个简单的例子,比如有个字符串"/id:12345/ts:987697413/user:678254& ...
- 【正则表达式1】C++11正则表达式
https://www.cnblogs.com/pukaifei/p/5546968.html [正则表达式1]C++11正则表达式 头文件 #include <regex> rege ...
- python进阶11 正则表达式
python进阶11 正则表达式 一.概念 #正则表达式主要解决什么问题? #1.判断一个字符串是否匹配给定的格式,判断用户提交的又想的格式是否正确 #2.从一个字符串中按指定格式提取信息,抓取页面中 ...
- 零元学Expression Blend 4 - Chapter 11 用实例了解布局容器系列-「Border」
原文:零元学Expression Blend 4 - Chapter 11 用实例了解布局容器系列-「Border」 将教大家以实做案例认识Blend 4 的布局容器,此章介绍的布局容器是Blend ...
随机推荐
- 【技术分享】Java 序列化与反序列化安全分析
唯品会安全应急响应中心 https://mp.weixin.qq.com/s?src=11×tamp=1546915765&ver=1317&signature=mW ...
- Best Cow Line---poj3617(贪心)
题目链接:http://poj.org/problem?id=3617 题意:有n头牛.刚开始有一个序列.现在想要重新排列.每次从原始的序列头部和尾部取出一个取出一个放到新的序列尾部.最后使得得到的新 ...
- 【小甲鱼】【Python】正则表达式(二)
>>> import re#|表示或的意思 >>> re.search(r"Fish(C|D)","FishC") < ...
- python3专业版安装及破解
1.网址 https://www.jetbrains.com/pycharm/download/#section=windows,打开页面,点击下载专业版 2.这是下载好的文件,双击运行即可. //详 ...
- RAC禁用DRM特性
查看"_gc"开头的隐藏参数值: set linesize 333 col name for a35 col description for a66 col value for a ...
- Twitter OA prepare: even sum pairs
思路:无非就是扫描一遍记录奇数和偶数各自的个数,比如为M和N,然后就是奇数里面选两个.偶数里面选两个,答案就是M(M-1)/2 + N(N-1)/2
- Problem B. Full Binary Tree
题目 链接:http://code.google.com/codejam/contest/2984486/dashboard#s=p1 googlde code jam 2014 Round1A 解题 ...
- js中sort()方法冒泡排序模拟
1.sort()方法概述 sort() 方法用于对数组的元素进行排序. 如果调用该方法时没有使用参数,将按字母顺序对数组中的元素进行排序,说得更精确点,是按照字符编码的顺序进行排序.要实现这一点, 首 ...
- JavaScript循环练习2
折纸:折多少次和珠穆朗玛峰一样高1.一张纸的厚度是0.0001米,将纸对折,对折多少次厚度超过珠峰高度8848米 var hou = 0.0001; var cishu = 0; for(var i= ...
- php深入学习
关于PHP程序员解决问题的能力 http://rango.swoole.com/archives/340 深入理解PHP内核 by xuhong大牛 http://www.php-internals. ...