正则表达式
今日目标:
- 理解正则表达式的作用
- 掌握正则表达式的基本写法
- 掌握正则表达的边界符、两次的用法
1. 正则表达式概述
正则表达式: 有规律的表达式。 就是设置规律,然后判断某一个字符串是否符合这种规律。
用途:
-
判断表单输入内容是否符合要求
-
替换字符串中的关键词
2. 正则的基本使用
- QRegExp 类用来实例化正则表达式
- indexIn() : 该方法用来检测字符串中是否有符合正则表达式的组合,返回索引号
创建正则表达式的两种方式:
// abc 即为正则表达式, 意思是只要字符串中有 "abc" 即符合要求
QRegExp r1("abc");
qDebug() << r1.indexIn("abc"); // 0
qDebug() << r1.indexIn("abcabc"); // 0
qDebug() << r1.indexIn("dabc"); // 1
qDebug() << r1.indexIn("adbc"); // -1
3. 边界符
- ^ (shift + 6): 定义以什么开头
- $ (shift + 4): 定义以什么结尾
- 如果正则表达式同时设置 ^ 和 $,则是完全匹配
// ^abc : 以 abc 开头
QRegExp r2("^abc");
qDebug() << r2.indexIn("abc"); // 0
qDebug() << r2.indexIn("abcabc"); // 0
qDebug() << r2.indexIn("dabc"); // -1
qDebug() << r2.indexIn("adbc"); // -1
QRegExp r3("abc$");
qDebug() << r3.indexIn("abc"); // 0
qDebug() << r3.indexIn("abcabc"); // 3
qDebug() << r3.indexIn("dabc"); // 1
qDebug() << r3.indexIn("adbc"); // -1
QRegExp r4("^abc$");
qDebug() << r4.indexIn("abc"); // 0
qDebug() << r4.indexIn("abcabc"); // -1
qDebug() << r4.indexIn("dabc"); // -1
qDebug() << r4.indexIn("adbc"); // -1
案例: 点提交按钮时检测用户输入的邮箱地址, 如果以 @126.com 结尾则提示成功,否则提示邮箱错误
QRegExp emailReg("@126.com$");
QString emailStr = ui->emailLine->text();
int result = emailReg.indexIn(emailStr);
if (result == -1)
{
QMessageBox::critical(this, "错误", "本项目只支持126邮箱");
}
else
{
QMessageBox::information(this, "提示", "邮箱地址正确");
}
5. 字符类
[] : 使用[]包含的意思是只要匹配到其中之一即可, 相当于是或的意思 a || b || c
QRegExp reg("abc"); // 必须完全匹配abc
QRegExp reg("[abc]"); // 只要能匹配到abc三个字符串其中之一即可 a || b || c
QRegExp reg("(a|b|c)"); // [abc] <===> [a|b|c]
QRegExp reg("[abcdefg]"); // <===> [a-g]
QRegExp reg("[a-z]"); // 匹配到26个小写字母
示例:
QRegExp r1("abc");
qDebug() << r1.indexIn("aaabc");
qDebug() << r1.indexIn("abc");
QRegExp r2("[abc]");
qDebug() << r2.indexIn("aaabc");
qDebug() << r2.indexIn("abc");
qDebug() << r2.indexIn("qwera");
QRegExp r3("[a-zA-Z]");
QRegExp r4("[a-zA-Z0-9]");
qDebug() << r3.indexIn("我是字母a");
qDebug() << r4.indexIn("我是007,詹姆斯.邦德");
在 [] 中也能使用 ^ 意思是取反
QRegExp r5("[a-zA-Z_]"); // 字符串中必须有 a-zA-Z_ 其中之一
QRegExp r6("^[a-zA-Z_]"); // 字符串必须以 a-zA-Z_ 开头
QRegExp r7("[^a-zA-Z_]"); // 字符不是 a-zA-Z_
qDebug() << r5.indexIn("Jack");
qDebug() << r5.indexIn("007-Jack");
qDebug() << r6.indexIn("o");
qDebug() << r7.indexIn("#");
6. 量词符
量词符: 用来定义模式出现的次数
第一类: 三种通配符
QRegExp r8("^a$"); //必须以a开头和结尾 --> 就是 a
qDebug() << r8.indexIn("a");
qDebug() << r8.indexIn("aa");
// 1. * 相当于 >= 0 可以出现0次或者很多次
QRegExp r9("^a*$");
qDebug() << r9.indexIn("");
qDebug() << r9.indexIn("a");
qDebug() << r9.indexIn("aa");
qDebug() << r9.indexIn("aaaaaaa");
// 2. + 相当于 >= 1 可以出现1次或者很多次
QRegExp r10("^a+$"); //a 可以出现1到多次
qDebug() << r10.indexIn("");
qDebug() << r10.indexIn("a");
qDebug() << r10.indexIn("aa");
qDebug() << r10.indexIn("aaaaaaa");
// 3. ? 相当于 1 || 0
QRegExp r11("^a?$"); //a 可以出现0次或者1次
qDebug() << r11.indexIn("");
qDebug() << r11.indexIn("a");
qDebug() << r11.indexIn("aa");
qDebug() << r1.indexIn("aaaaaaa");
第二类: 使用 {} 自定义匹配次数
使用{}定义次数时,逗号之后不能有空格
// 1. {3} 就是重复3次
QRegExp r12("^a{3}$");
qDebug() << r12.indexIn("");
qDebug() << r12.indexIn("a");
qDebug() << r12.indexIn("aaa");
qDebug() << r12.indexIn("aaaaaaa");
// 2. {3, } 大于等于3
QRegExp r13("^a{3,}$");
qDebug() << r13.indexIn("");
qDebug() << r13.indexIn("a");
qDebug() << r13.indexIn("aaa");
qDebug() << r13.indexIn("aaaaaaa");
// 3. {3, 6} 大于等于3 并且 小于等于6
QRegExp r14("^a{3,6}$"); //{3,6} 正确 ; {3, 6} 有空格,错误
qDebug() << r14.indexIn("");
qDebug() << r14.indexIn("a");
qDebug() << r14.indexIn("aaa");
qDebug() << r14.indexIn("aaaaaa");
qDebug() << r14.indexIn("aaaaaaaa");
7. 用户名验证
用户名要求: 6-16位 字母数字下划线组合
QRegExp userReg("^[a-zA-Z0-9_]$");
思路:
- 设置用户名检测的正则表达式
- 设置 QLabel 用来提示用户名规则以及正确和错误信息
- 为用户名文本框设置 textChanged 信号和槽
- 槽函数:
- 获取用户填写的用户名
- 使用 indexIn 验证获取到的用户名
- 当返回 >=0 时,QLabel 设置 ‘用户名正确’ 的信息
- 当返回为 -1时,QLabel 设置 ‘用户名格式错误’ 的信息
QRegExp userReg("^[a-zA-Z0-9_]{6,16}$");
if (userReg.indexIn(arg1) == -1)
{
ui->userLabel->setText("用户名不符合规则");
}
else
{
ui->userLabel->setText("用户名正确");
}
8. 括号
在线测试工具: https://c.runoob.com/front-end/854
- 小括号: 提升运算优先级 ()
- 大括号: 量词符, 里面表示重复次数 {}
- 中括号: 字符集合, 匹配方括号中的任意字符 []
//验证电话号码
QRegExp telReg("^1(3[-09]|47|5[0-9]|77|8[0-9])[0-9]{8}$");
qDebug() << telReg.indexIn("11094858374");
qDebug() << telReg.indexIn("13094858374");
qDebug() << telReg.indexIn("14594858374");
qDebug() << telReg.indexIn("15794858374");
qDebug() << telReg.indexIn("17894858374");
qDebug() << telReg.indexIn("18894858374");
//验证邮箱必须是 126.com 或者 163.com 邮箱
QRegExp emailReg("^[a-zA-Z0-9_]{2,}@(126.com|163.com)$");
qDebug() << emailReg.indexIn("andy@163.com");
qDebug() << emailReg.indexIn("andy007@126.com");
qDebug() << emailReg.indexIn("wang8@sina.com");
qDebug() << emailReg.indexIn("ergou@123.com");
//验证商品价格范围必须在: 100.00 - 99999.99 之间
QRegExp priceReg("^[1-9][0-9]{2,4}.[0-9]{2}$");
qDebug() << priceReg.indexIn("100.00");
qDebug() << priceReg.indexIn("99999.99");
qDebug() << priceReg.indexIn("10.999");
9. 预定义类
预定义类就是将经常使用的模式进行了事先定义,项目开发的时候直接使用即可
简化案例:
//验证电话号码
QRegExp telReg("^1(3\d|47|5\d|77|8\d)\d{8}$");
//验证邮箱必须是 126.com 或者 163.com 邮箱
QRegExp emailReg("^\w{2,}@(126.com|163.com)$");
//验证商品价格范围必须在: 100.00 - 99999.99 之间
QRegExp telReg("^[1-9]\d{2,4}.\d{2}$");
10. 表单验证
11. 替换
- str.replace(reg, s); replace 在进行字符串内容替换时可以使用正则达表达式方式来查找替换目标
- 参数1: 正则表达式,使用该正则表达式设置要被替换的字符串格式
- 参数2: 使用该字符串进行替换
- 忽略大小写:
- 创建正则表达式时,使用 Qt::CaseInsensitive 枚举值
- QRegExp r(“lj”, Qt::CaseInsensitive);
QRegExp r("(垃圾|laji|lj)", Qt::CaseInsensitive);
QString str = "你个垃圾,大垃圾,超级laji,lj,大Lj";
qDebug() << str.replace(r, "**");
单验证
11. 替换
- str.replace(reg, s); replace 在进行字符串内容替换时可以使用正则达表达式方式来查找替换目标
- 参数1: 正则表达式,使用该正则表达式设置要被替换的字符串格式
- 参数2: 使用该字符串进行替换
- 忽略大小写:
- 创建正则表达式时,使用 Qt::CaseInsensitive 枚举值
- QRegExp r(“lj”, Qt::CaseInsensitive);
QRegExp r("(垃圾|laji|lj)", Qt::CaseInsensitive);
QString str = "你个垃圾,大垃圾,超级laji,lj,大Lj";
qDebug() << str.replace(r, "**");