17.3 Regular Expressions(正则表达式)
一个正则表达式是描述字符串序列的方法。
| 式子 | 说明 |
| regex | 表示有一个正则表达式的类 |
| regex_match | 将一个字符序列与一个正则表达式匹配 |
| regex_search | 寻找第一个去正则表达式匹配的子序列 |
| regex_replace | 使用给定格式替换一个正则表达式 |
| sregex_iterator | 迭代器适配器,调用regex_search来遍历一个string中所有匹配子串 |
| smatch | 容器类,保存在string中搜索结果 |
| ssub_match | string中匹配的子表达式的结果 |
#include <iostream> #include <string> #include <regex> #include <vector> using namespace std; int main() { string pattern = "[^c]ie"; pattern = "[[:alpha:]]*" + pattern + "[[:alpha:]]*"; regex r(pattern, regex::icase); smatch results; string str; while (cin >> str) { if (str == "q") break; if (regex_search(str, results, r)) cout << results.str() << endl; } system("PAUSE"); return 0; }
[^c]ei表示不是c在ei前面的字符串。默认情况下,regex使用的正则表达式语言是ECMAScript.在ECMAScript中,模式[[:alpha:]]匹配任意字母,符号+和*分别表示我们希望“一个或多个”或“零个或多个”匹配。因此[[:alpha:]]将匹配零个或多个字母。
| 式子 | 说明 |
| regex r(re) | re表示一个正则表达式 |
| regex r(re, f) |
f是指出对象如何处理的标志,f通过下面的列出的值来设置, 如果未指定f,默认为ECMAScript |
| r1 = re | r1中的正则表达式替换为re |
| r1.assign(re,f) | 与使用=效果相同,f与上面f意义相同 |
| r.mark_count() | r中表达式的数目 |
| r.flags() | 返回r的标志集 |
定义在regex和regex_constants::syntax_option_type中
f为下面这些值
| 式子 | 说明 |
| icase | 在匹配过程中忽略大小写 |
| nosubs | 不保存匹配的子表达式 |
| optimize | 执行速度优先于构造速度 |
| ECMAScript | 使用ECMA-262指定语法 |
| basic | 使用POSIX基本的正则表达式语法 |
| extended | 使用POSIX扩展的正则表达式语法 |
| awk | 使用POSIX版本的awk语言的语法 |
| grep | 使用POSIX版本的grep的语法 |
| egrep | 使用POSIX版本的egrep的语法 |
#include <iostream> #include <regex> #include <string> using namespace std; int main() { regex r("[[:alnum:]]+\\.(cpp|cxx|cc)$", regex::icase); smatch results; string filename; while(cin >> filename){ if(regex_search(filename, results, r)) cout << results.str() << endl; } system("PAUSE"); return 0; }
在正则表达式中, 小数点(.)表示匹配任意字符串,在字符串中要表示一个普通的反斜线需要写成\\
在字符串前置一个反斜线去掉其特殊含义
获取正则表达式错误的方法:
#include <iostream> #include <regex> #include <string> using namespace std; int main() { try{ regex r("[[:alnum:]+\\.(cpp|cxx|cc)$", regex::icase); }catch(regex_error e){ cout << e.what() <<"\ncode:" << e.code() << endl; } smatch results; /*string filename; while(cin >> filename){ if(regex_search(filename, results, r)) cout << results.str() << endl; }*/ system("PAUSE"); return 0; }
code()返回某个错误类型对应的数值编码
当我们将filename直接写成"hello.cc"时,这时变量类型为char*,应该使用cmatch储存结果。

如果你在一个循环中使用正则表达式,应该在循环外创建它,而不是在每步迭代时都编译它。
使用regex迭代器类型搜寻
#include <iostream> #include <regex> #include <string> #include <vector> using namespace std; int main() { string pattern = "[^c]ei"; pattern = "[[:alpha:]]*" + pattern + "[[:alpha:]]*"; regex r(pattern,regex::icase); string file; while (getline(cin, file)) { if (file == "q") break; for (sregex_iterator it(file.begin(), file.end(), r), end_it; it != end_it; ++it) { cout << it->str() << endl; } } system("PAUSE"); return 0; }
定大小输出匹配结果上下文
#include <iostream> #include <string> #include <regex> using namespace std; int main() { string pattern("[^c]ei"); pattern = "[[:alpha:]]*" + pattern + "[[:alpha:]]*"; regex r(pattern, regex::icase); string str; while (getline(cin, str)) { if (str == "q") break; for (sregex_iterator it(str.begin(), str.end(), r), it_end; it != it_end; ++it) { auto pos = it->prefix().length(); pos = pos > 40 ? pos - 40 : 0; cout << it->prefix().str().substr(pos) << "\n\t<<<" << it->str() << "<<<\n" << it->suffix().str().substr(1, 40) << endl; } } system("PAUSE"); return 0; }

#include <iostream> #include <regex> #include <string> #include <fstream> using namespace std; bool checknum(const smatch& s) { if (s[1].matched) { return s[3].matched&& s[4].str() != "-" && s[4].str() != "."; } else return !s[3].matched && (s[4].str() == s[7].str()); } int main() { string pattern = "(\\()?(\\d{3})(\\))?([-.]|(\\s)*)?(\\d{3})([-.]|(\\s)*)?(\\d{4})"; //string fmt = "$2.$6.$9"; regex r(pattern); ifstream ss("D:\\test.txt", ios::in|ios::out); if (!ss) { cerr << "open failed!" << endl; system("PAUSE"); return 1; } string line; while (getline(ss, line)) { if (line == "q") break; for (sregex_iterator it(line.begin(), line.end(), r), it_end; it != it_end; ++it) { if (checknum(*it)) { //cout << "号码匹配正确:" << it->format(fmt) << endl; cout << it->str() << endl; } else { cout << "号码匹配错误。" << endl; } } } system("PAUSE"); return 0; }
注释部分为替换操作,可以使用format,也可以使用regex_replace
要使用匹配标志,需要明确声明using namespace std::regex_constants;

#include <iostream> #include <regex> #include <string> #include <fstream> using namespace std; using namespace std::regex_constants; bool checknum(const smatch& s) { if (s[1].matched) { return s[3].matched&& s[4].str() != "-" && s[4].str() != "."; } else return !s[3].matched && (s[4].str() == s[7].str()); } int main() { string pattern = "(\\()?(\\d{3})(\\))?([-.]|(\\s)*)?(\\d{3})([-.]|(\\s)*)?(\\d{4})"; string fmt = "$2.$6.$9"; regex r(pattern); ifstream ss("D:\\test.txt", ios::in|ios::out); if (!ss) { cerr << "open failed!" << endl; system("PAUSE"); return 1; } string line; while (getline(ss, line)) { if (line == "q") break; for (sregex_iterator it(line.begin(), line.end(), r), it_end; it != it_end; ++it) { if (checknum(*it)) { cout << "号码匹配正确:" << regex_replace(line, r, fmt, format_no_copy) << endl; //cout << it->str() << endl; } else { cout << "号码匹配错误。" << endl; } } } system("PAUSE"); return 0; }

浙公网安备 33010602011771号