使用正则表达式需要包含
#include
具有特殊意义的元字符
\:\字符能够改变字符原本的含义
^:^字符指示字符串的头,且要求字符串以字符开头,不占位。\^表示一个真正的^符号 (特殊字符具有特殊含义,如果字符串中有^,用\^表示字符本身)。
$:$字符指示字符串的尾,且要求字符串以字符结尾,不占位。\$表示一个真正的$符号。
():分组,大正则中包含小正则。可以改变默认的优先级。在模式中可以使用\1来表示第一组已然捕获到的东西(已匹配到的项)。
\b:指示字符串的边界(头/尾/空格左/空格右),字符\b要求边界的左边是字符,\b字符要求边界的右边是字符。
.:表示一个除了\n以外的任意一个字符。\.表示一个真正的.符号。
|:a | b a或b之一
[abc]:abc之中的任意一个
[^abc]:abc之外的
[a-z]:任意小写字母
[^a-z]:除了小写字母之外的
\w:任意一个字母数字下划线,等价于[(0-9)(a-z)(A-Z)(_)]
\W:字母数字下划线之外的任何一个字符,等价于[]
\d:任意一个数字
\D:除了数字之外的其他字符
\s:空白符(空格、制表符、换页符)
量词元字符
*:字符*要求字符出现0或更多次 {0,}
+:字符+要求字符出现1或更多次 (\w) {1,}
?:字符?要求字符出现0次或1次 {0,1}
{n}:字符{n}要求字符出现n次
{n,}:字符{n,}要求字符出现n或更多次 {0,}
{n,m}:字符{n,m}要求字符出现n到m次
所以含有\的元字符,在C++定义时,都要写成\\
校验数字的表达式
数字:^ [0 - 9] * $
n位的数字:^ \d{ n }$
至少n位的数字:^ \d{ n, }$
m - n位的数字: ^ \d{ m,n }$
零和非零开头的数字: ^ (0 | [1 - 9][0 - 9] *)$
非零开头的最多带两位小数的数字: ^ (\[1 - 9][0 - 9] *) + (.[0 - 9]{ 1,2 }) ? $
带1 - 2位小数的正数或负数: ^ (\ - ) ? \d + (\.\d{ 1,2 }) ? $
正数、负数、和小数: ^ (\ - | \ + ) ? \d + (\.\d + ) ? $
有两位小数的正实数: ^ [0 - 9] + (.[0 - 9]{ 2 }) ? $
有1~3位小数的正实数: ^ [0 - 9] + (.[0 - 9]{ 1,3 }) ? $
非零的正整数: ^ [1 - 9]\d * $ 或 ^ ([1 - 9][0 - 9] *) { 1, 3 }$ 或^ \ + ? \[1 - 9][0 - 9] * $
非零的负整数: ^ \ - [1 - 9][]0 - 9"$ 或 ^-[1-9]\d$
非负整数: ^ \d + $ 或 ^ [1 - 9]\d * | 0$
非正整数: ^ -[1 - 9]\d * | 0$ 或 ^ ((-\d + ) | (0 + ))$
非负浮点数: ^ \d + (.\d + ) ? $ 或 ^ [1 - 9]\d * .\d * | 0.\d * [1 - 9]\d * | 0 ? .0 + | 0$
非正浮点数: ^ ((-\d + (.\d + ) ? ) | (0 + (.0 + ) ? ))$ 或 ^ (-([1 - 9]\d * .\d * | 0.\d * [1 - 9]\d*)) | 0 ? \.0 + | 0$
正浮点数: ^ [1 - 9]\d * .\d * | 0.\d * [1 - 9]\d * $ 或 ^ (([0 - 9] + .[0 - 9] * [1 - 9][0 - 9] *) | ([0 - 9] * [1 - 9][0 - 9] * .[0 - 9] + ) | ([0 - 9] * [1 - 9][0 - 9] *))$
负浮点数: ^ -([1 - 9]\d * .\d * | 0.\d * [1 - 9]\d*)$ 或 ^ (-(([0 - 9] + .[0 - 9] * [1 - 9][0 - 9] *) | ([0 - 9] * [1 - 9][0 - 9] * .[0 - 9]) | ([0 - 9] * [1 - 9][0 - 9] *)))$
浮点数: ^ (-? \d + )(.\d + ) ? $ 或 ^ -? ([1 - 9]\d * .\d * | 0.\d * [1 - 9]\d * | 0 ? .0 + | 0)$
校验字符的表达式
汉字: ^ [\u4e00 - \u9fa5]{ 0, }$
英文和数字: ^ [A - Za - z0 - 9] + $ 或 ^ [A - Za - z0 - 9]{ 4,40 }$
长度为3 - 20的所有字符: ^ .{3, 20}$
由26个英文字母组成的字符串: ^ [A - Za - z] + $
由26个大写英文字母组成的字符串: ^ [A - Z] + $
由26个小写英文字母组成的字符串: ^ [a - z] + $
由数字和26个英文字母组成的字符串: ^ [A - Za - z0 - 9] + $
由数字、26个英文字母或者下划线组成的字符串: ^ \w + $ 或 ^ \w{ 3,20 }$
中文、英文、数字包括下划线: ^ [\u4E00 - \u9FA5A - Za - z0 - 9_] + $
中文、英文、数字但不包括下划线等符号: ^ [\u4E00 - \u9FA5A - Za - z0 - 9] + $ 或 ^ [\u4E00 - \u9FA5A - Za - z0 - 9]{ 2,20 }$
可以输入含有 ^ %&',;=?$"等字符:[^%&', ; = ? $\x22] + 12 禁止输入含有~的字符:[^ ~\x22] +
特殊需求表达式
Email地址: ^ \w + ([-+.]\w + ) * @\w + ([-.]\w + ) * .\w + ([-.]\w + ) * $
域名:[a - zA - Z0 - 9][-a - zA - Z0 - 9]{ 0,62 }(/ .[a - zA - Z0 - 9][-a - zA - Z0 - 9]{ 0,62 }) + / . ? InternetURL:[a - zA - z] + ://\s* 或 ^http://([\w-]+.)+[\w-]+(/[\w-./?%&=])?$
手机号码: ^ (13[0 - 9] | 14[5 | 7] | 15[0 | 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9] | 18[0 | 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9])\d{ 8 }$ 电话号码(0511 - 4405222、021 - 87888822):\d{ 3 } - \d{ 8 } | \d{ 4 } - \d{ 7 }
身份证号(15位、18位数字): ^ \d{ 15 } | \d{ 18 }$
短身份证号码(数字、字母x结尾): ^ ([0 - 9]) { 7, 18 }(x | X) ? $ 或 ^ \d{ 8,18 } | [0 - 9x]{ 8,18 } | [0 - 9X]{ 8,18 } ? $
帐号:(字母开头,允许5 - 16字节,允许字母数字下划线): ^ [a - zA - Z][a - zA - Z0 - 9_]{ 4,15 }$
密码:(以字母开头,长度在6~18之间,只能包含字母、数字和下划线): ^ [a - zA - Z]\w{ 5,17 }$
强密码(必须包含大小写字母和数字的组合,不能使用特殊字符,长度在8 - 10之间): ^ (? = .\d)(? = .[a - z])(? = .*[A - Z]).{8, 10}$
日期格式: ^ \d{ 4 } - \d{ 1,2 } - \d{ 1,2 } 一年的12个月(01~09和1~12): ^ (0 ? [1 - 9] | 1[0 - 2])$
一个月的31天(01~09和1~31): ^ ((0 ? [1 - 9]) | ((1 | 2)[0 - 9]) | 30 | 31)$
xml文件: ^ ([a - zA - Z] + -? ) + [a - zA - Z0 - 9] + \\.\[x | X]\[m | M][l | L]$
中文字符的正则表达式:[\u4e00 - \u9fa5]
双字节字符:\[^ \x00 - \xff](包括汉字在内,可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1))
空白行的正则表达式:\n\s * \r(可以用来删除空白行)
HTML标记的正则表达式:<(\S* ? ) > >. ? < / \1> | <.* ? / > (复杂的嵌套标记依旧无能为力)
首尾空白字符的正则表达式: ^ \s * | \s * $或(^ \s*) | (\s * $) (可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等))
腾讯QQ号:[1 - 9][0 - 9]{ 4, } (腾讯QQ号从10000开始)
中国邮政编码:[1 - 9]\d{ 5 }(? !\d) (中国邮政编码为6位数字)
IP地址:\d + .\d + .\d + .\d + (提取IP地址时有用)
IP地址:((? : (? : 25[0 - 5] | 2[0 - 4]\d | [01] ? \d ? \d)\.) { 3 }(? : 25[0 - 5] | 2[0 - 4]\d | [01] ? \d ? \d))
例如匹配邮箱,注意把空格去掉,并把单斜杆变成双斜杠
调用函数:bool regex_match(string str,regex reg);
第一个参数是要匹配的字符串,第二个参数是正则规则 / 对象
返回值:满足要求返回true 不满足返回false
正则匹配,一定是完全匹配
实例:
//构建正则规则
regex reg("^[A-Za-z0-9]{4,40}$");//字母数字长度4-40
//账户名
string userName;
bool result = regex_match(userName, reg);
if (result)
{
cout << "符合账户名规则" << endl;
break;
}
//匹配“四个数字-一个或俩个数字”
#include
#include
using namespace std;
int main()
{
string str;
cin >> str;
//\d 表示匹配数字 {4} 长度4个 \d{1,2}表示匹配数字长度为1-2
cout << regex_match(str, regex("\\d{4}-\\d{1,2}"));
return 0;
}
//匹配邮箱 “大小写字母或数字@126/163.com”
int main()
{
string str;
cout << "请输入邮箱:" << endl;
while (cin >> str)//匹配邮箱
{
if (true == regex_match(str, regex("[a-zA-Z0-9]+@1(26|63)\\.com")))
{
break;
}
cout << "输入错误,请重新输入:" << endl;
}
cout << "输入成功!" << endl;
return 0;
}
调用函数: string regex_replace(string str,regex reg, string newstr);
第一个参数是要匹配的字符串,第二个参数是正则规则 / 对象,第三个参数是要把满足规则的替换成某一个新的字符
返回值:返回一个新的字符串
实例:
string str = "ILoveyou1314520";
regex reg("\\d+");//把字符串中多个数字替换成"一生一世"
cout << "str:" << regex_replace(str, reg, "一生一世") << endl;
//如何控制替换
//1.只替换第一次出现的不替换后面搜索出现符合规则的
cout << "onlyfirst:" << regex_replace(str, reg, "一生一世",regex_constants::format_first_only) << endl;
//2.不拷贝其它内容只输出符合规则更改后的部分
cout << "nocopy:" << regex_replace(str, reg, "一生一世", regex_constants::format_no_copy) << endl;
//3.默认方式直接替换符合规则部分输出
cout<<"default:"<< regex_replace(str, reg, "一生一世", regex_constants::format_default) << endl;
//4.sed格式规则
cout << "sed:" << regex_replace(str, reg, "一生一世", regex_constants::format_sed) << endl;
}
/* 输出 */
str:ILoveyou一生一世
onlyfirst:ILoveyou一生一世
nocopy:一生一世
default:ILoveyou一生一世
sed:ILoveyou一生一世
//替换匹配,即可以将符合匹配规则的子字符串替换为其他字符串。
//将字符串中的-替换为/
#include
#include
using namespace std;
int main()
{
//替换不会修改原串
cout << regex_replace("2019-08-07", regex("-"), "/") << endl;
return 0;
}
调用函数:bool regex_search(string str,smatch result,regex reg);
第一个参数是要匹配的字符串,第二个参数 smatch 用来保存捕获到的结果,第三个参数是正则表达式对象
返回值:bool 类型
using smatch = match_results
smatch 存储捕获到的字符串的前缀和后缀
假设匹配到 1314,前缀就是 ILoveyou,后缀就是 IMissyou520me
如果没有后缀,获取的就是空字符,写一个循环判断后缀是否为空即可,如果不为空,就一直做截取,就可以把每一个匹配到的都截取出来
//正常截取处理匹配项
string str = "ILoveyou1314IMissyou520me";
//存储结果
smatch result;
//捕获处理-> 捕获多个数字
bool flag = regex_search(str, result, regex("\\d+"));
if (flag)
{
cout << "size:" << result.size() << endl;
//匹配到的字符串存储在result中
for (int i = 0; i < result.size(); i++)
{
//获取匹配到字符串
cout << result.str() << endl;
}
//匹配到的字符串的前缀
cout << "pre:" << result.prefix() << endl;
//匹配到的字符串的后缀
cout << "suf:" << result.suffix() << endl;
}
cout << "str:" << str << endl;
//把每一块找到的都截取出来 result.suffix作为循环条件去持续截取即可
// srgex_iterator
regex rule("\\d+");
//构建位置:原字符串开始位置 原字符串结束位置 这一串按照rule正则规则去截取
sregex_iterator pos(str.begin(), str.end(), rule);
//无参构造代表结束
sregex_iterator end; //end_of_iterator
//当前位置不等于结束位置
while (pos != end)
{
//获取数据
cout << pos->str() << endl;
pos++;
}
//拆解字符串
//sregex_token_iterator(iterator begin,iteartor end,regex regex, int flag);
//flag: 0 存储所有匹配的,-1 存储所有不匹配的
regex regexRule("\\d+");
//原字符串开始位置 原字符串结束位置 规则 标记
sregex_token_iterator Begin(str.begin(), str.end(), regexRule, 0);
//无参构造代表结束
sregex_token_iterator End;
while (Begin != End)
{
//获取数据
cout << Begin->str() << endl;
Begin++;
}
cout << endl;
/* 输出 */
size:1
//匹配到的字符串
1314
//前缀
pre:ILoveyou
//后缀
suf:IMissyou520me
str:ILoveyou1314IMissyou520me
//把后续满足条件的每一部分都截取出来
1314
520
//获取所有匹配的-> 按照正则规则把每一部分都拆解出来
1314
520
//搜索匹配,即搜索字符串中存在符合规则的子字符串。
//用法一:匹配单个
#include
#include
#include
using namespace std;
int main()
{
string str = "hello2019-02-03word";
smatch match;//搜索结果
regex pattern("(\\d{4})-(\\d{1,2})-(\\d{1,2})");//搜索规则 ()表示把内容拿出来
if (regex_search(str, match, pattern))
{ //提取 年 月 日
cout << "年:" << match[1] << endl;
cout << "月:" << match[2] << endl;
cout << "日:" << match[3] << endl;
//下标从1开始 下标0存的是符合这个搜索规则的起始位置和结束位置
}
return 0;
}
//用法二:匹配多个
#include
#include
#include
using namespace std;
int main()
{
//匹配多个符合要求的字符串
string str = "2019-08-07,2019-08-08,2019-08-09";
smatch match;
regex pattern("(\\d{4})-(\\d{1,2})-(\\d{1,2})");
string::const_iterator citer = str.cbegin();
while (regex_search(citer, str.cend(), match, pattern))//循环匹配
{
citer = match[0].second;
for (size_t i = 1; i < match.size(); ++i)
{
cout << match[i] << " ";
}
cout << endl;
}
return 0;
}