许多同学告诉我qt中正则表达式是一个很强大的类QRegExp,所以我通过网上的博客和各种资料以及课本对正则表达式进行了学习各种博客上的内容都很好,但是都不是很全面。所以我本文是对其他人文章的总结。以及自己的一些思考和看法,和学习到的知识点。如何使用这个类。
在项目中我们经常会遇到对字符串进行操作的情况,可以直接使用QString的一些函数,在这里QT提供了了一个类――QRegExp,使用正则表达式来操作字符串。学习一个事物最好的方式是从理论入手,了解清楚之后再去面向实例加以实践。最后将我们的知识掌握下来,就可以说是一次较为成功的学习了。
基本介绍知识
正则表达式(Regular Expression,通常简写为RegExp、RE等),预先定义一些字符或字符的组合,用于匹配文本中的一段字符串。
QRegExp是Qt的正则表达式类,Qt中有两个不同类的正则表达式。第一类为元字符,它表示一个或多个常量表达式;另一类为转义字符,它代表一个特殊字符。
一.元字符
^ 匹配字符串首,例如, ^12可能是123,但不能是312
[] 匹配括号内输入的任意字符,[123]可以为1, 2 或3
+ 匹配至少一个前导字符,例如, 1+2必须为一个或多个1, 后跟一个2
二.统配模式
通过 QRegExp::setPatternSyntax(QRegExp::Wildcard);可以将元字符设置为统配模式.在统配模式下,只有3个元字 符可以使用.他们的功能没有变化.
? 匹配任意单个字符, 例如, 1?2可以为1,后面跟任意单个字符, 再跟2
* 匹配任意一个字符序列. 例如, 1*2, 可以为1, 后面跟任意数量的字符, 再跟一个2
三.转义序列
这些表达式均以\开始, 与C++的转义字符相同,所以为了定义QRegExp中的一个转义序列,需要在前面添加两个\\.
下面是它的几个用途:
1.验证
判断字符串是否符合某个标准,比如“是一个整数”或者“没有空格”。
//用正则表达式验证文本有效性 //你可以使用QRegExp::exactMatch来判断一个字符串是否符合一个pattern。 void testRegexMatch() { QString pattern(“.*=.*”); QRegExp rx(pattern); bool match = rx.exactMatch(“a=3〃); qDebug() << match; // True match = rx.exactMatch(“a/2〃); qDebug() << match; // False }2.搜索
QString::indexOf(QString) void simLighter::highlightBlock(const QString &text) { QTextCharFormat myClassFormat; QColor color(0,0,100,100); myClassFormat.setBackground(color); int index = text.indexOf(pattern); while (index >= 0) { int length = pattern.length(); //expression.matchedLength(); setFormat(index, length, myClassFormat); index = text.indexOf(pattern, index + length); } }3.查找并替换
正则表达式能够用一个不同的字符串,替换所有出现另一个字符串的地方,比如用&替换&,如果原先&后面已经有了amp;那么不替换。
相关的类和方法 QTextEdit::find(); QTextEdit::textCursor(); QTextEdit::insertText(); QTextEdit::movePosition(QTextCursor::Start);
4.分割字符串
比如,根据tab来分割字符串。
使用正则表达式首先需要了解一些符号的作用,比如\d用来匹配数字,下面结合一些例子说明。
| 例子 | 解释 |
|---|---|
[abc] | 方括号中间是几个字母,表示a,b,c这三个单独的字符 |
[^abc] | 除了a,b,c以外的字符 |
[a-z] | 横杠表示范围,匹配a到z之间(包括a和z)的所有单个字符 |
[a-zA-Z] | a到z、A到Z的所有单个字符 |
^ | 在一行最前 |
$ | 在一行的最后 |
\s | 匹配任意空白字符 |
\S | 匹配任意非空白的字符 |
\d | 任意数字 |
\D | 任意非数字 |
\w | 任意单字字符(字母、数字或下划线) |
\W | 任意非单字字符 |
(a|b) | a或b |
a? | ?代表0个或1个 |
a* | *代表0个或1个或多个 |
a+ | +代表1个或多个 |
a{3} | 3个a |
a{3,} | 3个或大于3个a |
a{3,6} | a的个数在3和6之间(包括3和6) |
注意:C++编译器会对反斜杠进行转换,要想在正则表达式中包括一个\,需要输入两次,例如\\s。要想匹配反斜杠本身,需要输入4次,比如\\\\。
Qt中的用法
1.对用户输入的限制void QLineEdit::setValidator(const QValidator * v)
QLineEdit中的这个函数意思是,令LineEidt只接受验证器 v 所匹配的输入,你可以对要输入的内容进行任意的限制。
比如:限制输入框只能输入0到99999
QRegExp regExp("0|[1-9]\\d{0,4}");
ui.lineEdit->setValidator(new QRegExpValidator(regExp, this));
2.检查输入是否符合格式
QValidator::State QRegExpValidator::validate(QString & input, int & pos) const如果输入与正则表达式相匹配,则返回Acceptable;如果部分匹配,则返回Intermediate(部分匹配,意思是如果给它增加额外的字符则能够匹配正则表达式);如果不匹配则返回Invalid。
enum QValidator::State这个枚举类型说明了被验证的字符串是哪种类型。
QValidator::Invalid:值为0,表示字符串完全不匹配;
QValidator::Intermediate:值为1,表示部分匹配;
QValidator::Acceptable:值为2,表示完全匹配。
// integers 1 to 9999 QRegExp rx("[1-9]\\d{0,3}"); // the validator treats the regexp as "^[1-9]\\d{0,3}$" QRegExpValidator v(rx, 0); QString s; int pos = 0; s = "0"; v.validate(s, pos); // returns Invalid s = "12345"; v.validate(s, pos); // returns Invalid s = "1"; v.validate(s, pos); // returns Acceptable rx.setPattern("\\S+"); // one or more non-whitespace characters v.setRegExp(rx); s = "myfile.txt"; v.validate(s, pos); // Returns Acceptable s = "my file.txt"; v.validate(s, pos); // Returns Invalid // A, B or C followed by exactly five digits followed by W, X, Y or Z rx.setPattern("[A-C]\\d{5}[W-Z]"); v.setRegExp(rx); s = "a12345Z"; v.validate(s, pos); // Returns Invalid s = "A12345Z"; v.validate(s, pos); // Returns Acceptable s = "B12"; v.validate(s, pos); // Returns Intermediate // match most 'readme' files rx.setPattern("read\\S?me(\.(txt|asc|1st))?"); rx.setCaseSensitive(false); v.setRegExp(rx); s = "readme"; v.validate(s, pos); // Returns Acceptable s = "README.1ST"; v.validate(s, pos); // Returns Acceptable s = "read me.txt"; v.validate(s, pos); // Returns Invalid s = "readm"; v.validate(s, pos); // Returns Intermediate^[0-9]+3c$
看上面的表达式,开头的^表示必须以[0-9]+开头,结尾的$表示必须以字母c结尾,如果输入的是123a,则返回QValidator::Intermediate,表示部分匹配,如果输入的是233abc,则完全匹配。
3.截取字符串
QString QRegExp::cap(int nth = 0) const这个函数返回被第n个子表达式捕获的文本,整个匹配拥有下标0,带括号的子表达式下标从1开始。QRegExp rxlen("(\\d+)(?:\\s*)(cm|inch)"); int pos = rxlen.indexIn("Length: 189cm"); if (pos > -1) { QString value = rxlen.cap(1); // "189" QString unit = rxlen.cap(2); // "cm" // ... }―― 引用来源网址 ――