环境:win732位旗舰版、VS2010旗舰版
使用正则表达式检索、替换那些符合某个模式的文本是非常方便的,这样就不用自己写查找的算法了^^。
#include <string> #include <regex> #include <ctime> #include <iostream> using namespace std; ////////////////////////////////////////////////////////////////////////// // 特殊含义字符 // . 除'\n'外任意单个字符 // [] 字符集 // {} 计数 // () 子模式 // * 0个或多个 // + 一个或多个 // ? 0个或一个 // | 或 // ^ 行的开始;否定 // $ 行的结束 // 字符集 // \d 一个十进制数字 // \l 一个小写字母 // \s 一个空白符(空格/制表符) // \u 一个大小字母 // \w 一个字母(A-Za-z)或数字(0-9)或下划线(_) // \D 除了\d之外的字符 // \L 除了\l之外的字符 // \S 除了\s之外的字符 // \U 除了\u之外的字符 // \W 除了\w之外的字符 // 重复 // {n} 严格重复n次 // {n,} 重复n次或更多次 // {n,m} 重复n-m次 // * {0,} // + {1,} // ? {0,1} ////////////////////////////////////////////////////////////////////////// //辅助函数 void Print(std::smatch& sm) { std::string s; if (sm.empty()) return; //显示匹配的字符串 cout << "match string:\t\t" << sm.str(0) << endl; for (int i = 1; i < sm.size(); ++i) { s = sm.str(i);//捕获的字符串 cout << "index:" << i << "\t\t" << s << endl; } cout << endl; } void Print(sregex_iterator& pos) { string s; sregex_iterator end; if (pos == end) return; for (; pos != end; ++pos) { int size = pos->size(); //显示匹配的字符串 cout << "match string:\t\t" << pos->str(0) << endl; for (int i = 1; i < size; ++i) { s = pos->str(i);//捕获的字符串 cout << "index:" << i << "\t\t" << s << endl; } } cout << endl; } //测试函数 void Test1() { string text; regex reg; text = "<name>\n<first>111111111111111111111111111111111111111111111111111</first>\n<second>2</second>\n</name>\n"; reg = "<(.*)>(.*)</\\1>"; time_t tm1, tm2; tm1 = time(NULL); for (int i = 0; i < 10000; ++i) { sregex_iterator pos(text.cbegin(), text.cend(), reg); Print(pos); } tm2 = time(NULL); cout << "Test1:\t" << tm2 - tm1 << endl; } void Test2() { string text; regex reg; text = "<name>\n<first>111111111111111111111111111111111111111111111111111</first>\n<second>2</second>\n</name>\n"; reg = "<(.*?)>(.*?)</\\1>"; time_t tm1, tm2; tm1 = time(NULL); for (int i = 0; i < 10000; ++i) { sregex_iterator pos(text.cbegin(), text.cend(), reg); Print(pos); } tm2 = time(NULL); cout << "Test2:\t" << tm2 - tm1 << endl; } int _tmain(int argc, _TCHAR* argv[]) { string text; regex reg; smatch sm; bool bRet = false; ////////////////////////////////////////////////////////////////////////// // "(.*?)" 匹配从'"'字符开始,任意个非'\n'字符并以'"'结尾的字符串 // ? 表示非贪心模式,贪心模式会匹配到最长"name"="123",而非贪心则匹配最短"name" ////////////////////////////////////////////////////////////////////////// text = "\"name\"=\"123\"\""; reg = "\"(.*?)\""; bRet = regex_search(text, sm, reg); if (bRet) Print(sm); ////////////////////////////////////////////////////////////////////////// // <(.*)>(.*)</\1> 表示匹配<A>...</A>这样的字符串 // <(.*)>(.*)</(.*)> 表示匹配<A>...</B>这样的字符串,A和B可以相等也可以不相等 // \1 表示该处的字符串和第一个捕获的字符串一样 ////////////////////////////////////////////////////////////////////////// text = "<name>\n<first>1</first>\n<second>2</second>\n</name>\n"; reg = "<(.*?)>(.*?)</\\1>"; bRet = regex_search(text, sm, reg); if (bRet) Print(sm); sregex_iterator pos8(text.cbegin(), text.cend(), reg); Print(pos8); ////////////////////////////////////////////////////////////////////////// // (\d+)\?(\d+) // (\d+) 表示匹配一个或多个数字字符 // \? 表示字符'?',与regex特殊字符冲突需要加'\' ////////////////////////////////////////////////////////////////////////// text = "123?456"; reg = "(\\d+)\\?(\\d+)"; bRet = regex_match(text, sm, reg); if (bRet) Print(sm); ////////////////////////////////////////////////////////////////////////// // "(?:[^"]+)":"([^"]+)" // (?:[^"]+) 表示匹配[^"]+,但是不获取匹配结果 ////////////////////////////////////////////////////////////////////////// text = "\"name\":\"123\",\"name\":\"456\",\"name\",\"789\""; reg = "\"(?:[^\"]+)\":\"([^\"]+)\""; sregex_iterator pos1(text.cbegin(), text.cend(), reg); Print(pos1); ////////////////////////////////////////////////////////////////////////// // "([mnop]{5})(.*)" // ([mnop]{5}) 表示匹配字符集('m','n','o','p')中的5个字符 ////////////////////////////////////////////////////////////////////////// text = "mnopmmnQrstuvwxyz"; reg = "([mnop]{5})(.*)"; bRet = regex_match(text, sm, reg); if (bRet) Print(sm); //捕获qq邮箱中的qq号码 text = "123456@qq.com"; reg = "([0-9A-Za-z]+)@(?:[A-Za-z]+)\\.com"; bRet = regex_match(text, sm, reg);//123456 if (bRet) Print(sm); ////////////////////////////////////////////////////////////////////////// // "[^z]+z(.*)" // [^z]+ 表示匹配非字符'z'一个或多个字符 // (.*) 表示匹配任意字符 ////////////////////////////////////////////////////////////////////////// text = "abcedfz123456"; reg = "[^z]+z(.*)"; bRet = regex_match(text, sm, reg);//123456 Print(sm); ////////////////////////////////////////////////////////////////////////// // "<(\S*?).*?>(.*?)</\1>" // <(\S*?) 表示从字符'<'开始匹配非空白字符0或多个,非贪婪模式,并存储匹配结果(A) // .*?> 表示匹配任意字符0个或多个,直到字符'>'为止,非贪婪模式,否则将匹配到最后一个为'>'的字符 // </\1> 表示匹配字符串"</"开始接着匹配A(第一个匹配的结果)字符并以字符'>'结尾 ////////////////////////////////////////////////////////////////////////// text = "<html show=\"1\">hello</html>" "<html>123</html>"; reg = "<(\\S*?).*?>(.*?)</\\1>"; sregex_iterator pos2(text.cbegin(), text.cend(), reg); Print(pos2); text = "<preson visible=\"1\">" "<name>aa</name>" "<age>18</age>" "<sex>女</sex>" "</preson>" "<preson visible=\"1\">" "<name>bb</name>" "<age>20</age>" "<sex>男</sex>" "</preson>"; reg = "<(\\S*?).*?>" //匹配<person > "<(\\S*?)>(.*?)</\\2>" //匹配<name></name> "<(\\S*?)>(.*?)</\\4>" //匹配<age></age> "<(\\S*?)>(.*?)</\\6>" //匹配<sex></sex> "</\\1>"; //匹配</person> sregex_iterator pos3(text.cbegin(), text.cend(), reg); Print(pos3); //将字符串"colour"替换为"color" text = "colour,colours,color,colourize"; reg = "(colo)(u)(r)"; string rep = "$1$3";//去除掉$2即字符'u' string out = regex_replace(text, reg, rep); //将字符串"<A>B</A>"替换为字符串"<A value="B" />" text = "<person>\n" "<first>Nico</first>\n" "<last>Josuttis</last>\n" "</preson>\n"; reg = "<(.*)>(.*)</\\1>"; rep = "<$1 value=\"$2\"/>"; out = regex_replace(text, reg, rep); //测试两个正则表达式的效率 Test1(); Test2(); return 0; }