C++11 新增了正则表达式的标准库支持,本文简介 C++ 正则表达式的使用
在 C++ 中使用正则表达式,和其它语言差别不大
1 2 3 4 5 6 7
| int main() { regex e("abc*"); bool match = regex_search("abccc", e);
cout << (match ? "Matched" : "Not matched") << endl; }
|
C++11 自带了 6 种正则表达式语法的支持
- ECMAScript
- basic
- extended
- awk
- grep
- egrep
C++11 默认使用 ECMAScript 语法,这也是 6 种语法中最强大的,假如想使用其他 5 种语法,只需在声明 regex
对象时指定即可
1
| regex e("^abc.", regex_constants::grep);
|
假如我们不仅仅想知道一个正则表达式是否匹配一个字符串,我们还想要提取出匹配的部分,例如我们需要从邮箱中提取用户名和网址,就需要用到 match_results
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| int main() { string str("Email a@bc.com is mine"); smatch m;
regex e("([[:w:]]+)@([[:w:]]+\\.com)"); bool found = regex_search(str, m, e);
cout << "m.size=" << m.size() << endl;
for (int n = 0; n < m.size(); n++) { cout << "m[" << n << "]=" << m[n].str() << endl; } cout << "m.prefix=" << m.prefix().str() << endl; cout << "m.suffix=" << m.suffix().str() << endl; }
|
假如我们想要匹配的字符串中,有多个子串都可以匹配正则表达式,并且我们想把这些子串全部找出来,例如一个字符串中包含多个邮箱地址,那么就需要用到 regex_iterator
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| int main() { string str("a@bc.com, d@ef.com, aa@bb.com");
regex e("([[:w:]]+)@([[:w:]]+\\.com)");
sregex_iterator pos(str.cbegin(), str.cend(), e); sregex_iterator end;
for (; pos!=end; pos++) { cout << "email=" << pos->str(0) << ", user=" << pos->str(1) << ", domain=" << pos->str(2) << endl; } }
|
如上我们可以看到,regex_iterator
其实就是迭代字符串中所有正则表达式匹配的 match_results
。
除此之外,C++ 还提供了另一种迭代器, regex_token_iterator
。不同的是,regex_token_iterator
迭代的是所有正则表达式匹配中的指定子表达式,或迭代未匹配的子字符串
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| int main() { string str("a@bc.com, d@ef.com, aa@bb.com");
regex e("([[:w:]]+)@([[:w:]]+\\.com)");
sregex_token_iterator pos(str.cbegin(), str.cend(), e); sregex_token_iterator end;
for (; pos!=end; pos++) { cout << "Matched: " << *pos << endl; } }
|
我们可以修改 pos
的定义,使它每次迭代 match_results
的第 2 个 group
1 2
| sregex_token_iterator pos(str.cbegin(), str.cend(), e, 2);
|
值得注意的是,如果我们把这里的参数设为 -1,则迭代字符串中所有不匹配正则表达式的部分,相当于用正则表达式切割字符串
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| int main() { string str("a bb cd");
regex e("\\s+");
sregex_token_iterator pos(str.cbegin(), str.cend(), e, -1); sregex_token_iterator end;
for (; pos!=end; pos++) { cout << "Matched: " << *pos << endl; } }
|
正则表达式还有一个常用的场景——字符串替换。C++ 中我们可以使用 regex_replace
1 2 3 4 5 6 7 8
| int main() { string str("a@bc.com, d@ef.com, aa@bb.com");
regex e("([[:w:]]+)@([[:w:]]+\\.com)");
cout << regex_replace(str, e, "$1 is on $2"); }
|