第二章 (补充)正则表达式

一、简介

Qt的QRegExp类是 正则表达式的表示类,它基于Prel的正则表达式语言,完全支持Unicode。

正则表达式(regular expression)由表达式(expressions)、量词(quantifiers)和断言(assertions)组成。

表达式(expressions):

最简单的表达式是一个字符。字符集可以使用表达式如"AEIOU",表示匹配所有的大写元音字母;使用"\^AEIOU",表示匹配所有非元音字母;连续的字符集可以使用表达式"a-z",表示匹配所有的小写英文字母。

|---------|---------------------------------------------|
| c | 匹配字符本身,如a匹配a |
| \c | 跟在\后面的字符匹配字符本身,但本表中下面指定的这些字符除外。 |
| \a | 匹配ASCII的振铃 |
| \f | 匹配ASCII的换页 |
| \n | 匹配ASCII的换行 |
| \r | 匹配ASCII的回车 |
| \t | 匹配ASCII的水平制表符 |
| \v | 匹配ASCII的垂直制表符 |
| \xhhhh | 匹配Unicode字符对应的十六进制数 |
| \0ooo | 匹配八进制的ASCII/Latin1字符 |
| . | 匹配任意字符 |
| \d | 匹配任意一个数字 |
| \D | 匹配一个非数字 |
| \s | 匹配一个空白字符,包括"\t"、"\n"、"\v"、"\f"、"\r"及"" |
| \S | 匹配一个非空白字符 |
| \w | 匹配一个单词字符,包括任意字符数字下划线,即A~Z,a~z,0~9中任意一个 |
| \W | 匹配一个非单词字符 |
| \n | 第n个反向引用 |

量词(quantifiers):

量词说明表达式出现的次数,如"x{1,2}"表示x可以出现至少一次,至多两次。

|------------|------------------|
| 量词 | 含义 |
| E? | 匹配0次或1次等价于E{0,1} |
| E+ | 匹配1次或多次,等价于E{1,} |
| E* | 匹配0次或多次,等价于E{0,} |
| E{n} | 匹配n次 |
| E{n,} | 匹配至少n次 |
| E{,m} | 匹配至多m次 |
| E{n,m} | 匹配至少n次,至多m次 |
[正则表达式的量词]

断言(assertions):

断言在regexp中作出一些有关文本的声明,它们不匹配任何字符。

|------------|-----------------------------|
| 断言 | 含义 |
| ^ | 标志字符串的开始。若匹配"^"则使用"\\^" |
| | 标志字符串的结尾。若匹配""则使用"\\$" |
| \b | 一个单词的边界 |
| \B | 一个非单词的边界。当\b为false则它为true |
| (?=E) | 表达式后紧跟E才匹配 |
| (?!E) | 表达式后不跟E才匹配 |
[断言]

通配符:

|-------------|---------------------|
| 通配符 | 含义 |
| c | 任意一个字符,表字符本身 |
| ? | 任意一个字符,类似regexp中"." |
| * | 任意0个或多个字符 |
| ... | 在\[\]中的字符集 |

二、练习

cpp 复制代码
#include <QCoreApplication>
#include <QDebug>
#include <QRegularExpression>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QRegExp reg("ab");
    qDebug() << "匹配字符本身:"
             << reg.exactMatch("abc")
             << reg.exactMatch("ab")
             << endl;

    QRegExp reg0("(\\d*\\D{2})");
    qDebug() << "匹配数字:"
             << reg0.exactMatch("183cm")
             << reg0.exactMatch("183m")
             << reg0.exactMatch("72in");

    QRegExp rx("*.txt");
    //设置匹配语法
    rx.setPatternSyntax(QRegExp::Wildcard);//支持通配符
    qDebug() << "通配符匹配:"
             << rx.exactMatch("License.txt")
             << rx.exactMatch("License.txt.bak")
             << endl;

    //匹配单词边界
    QRegExp reg1;
    //设置匹配模式
    reg1.setPattern("\\b(hello|Hello)\\b");
    qDebug() << "匹配多个单词:"
             << reg1.indexIn("helloEveryone!")      //-1表失败
             << reg1.indexIn("Hmm hello everyone!") //4,匹配到的字符位置
             << reg1.indexIn("Hi girls! Hello boys!")//10
             << endl;

    //捕获匹配的文本
    //非捕获括号语法:由 "(?:" 开始,")"结束
    QRegExp regHeight("(\\d+)(?:\\s*)(cm|inch)");
    int res = regHeight.indexIn("YaoMing 226 cm");
    if(res > -1){
        qDebug() << "文本捕获:"
                 << "cap(0):" << regHeight.cap(0)
                 << "cap(1):" << regHeight.cap(1)
                 << "cap(2):" << regHeight.cap(2)
                 << endl;
    }

    //断言?! 不紧跟才匹配
    QRegExp reg2;
    reg2.setPattern("面(?!包)");
    QString str = "面没了,吃面包也好,吃面食物也可以。";
    qDebug() << str << endl;
    str.replace(reg2,"意大利");
    qDebug() << str << endl;

    //Qt5引入了新的类
    QRegularExpression regExp("hello");
    qDebug() << "QRegularExpression 匹配字符:"
             << regExp.match("hello world!");

    regExp.setPattern("[A-Z]{3,8}");
    regExp.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
    qDebug() << "大小写不敏感匹配:"
             << regExp.match("hello");

    QRegularExpression reDate("^(\\d\\d)/(\\d\\d)/(\\d\\d\\d\\d)$");
    QRegularExpressionMatch match0 = reDate.match("01/10/1949");
    if( match0.hasMatch() ){
        QString strMatch = match0.captured(0);
        QString day = match0.captured(1);
        QString month = match0.captured(2);
        QString year = match0.captured(3);

        qDebug() << "捕获文本:"
                 << "strMatch:" << strMatch << endl
                 << "day:" << day << endl
                 << "month:" << month << endl
                 << "year:" << year;
    }

    QString sPattern;
    sPattern = "^(Jan|Feb|Mar|Apr|May) \\d\\d \\d\\d\\d\\d$";
    QRegularExpression reDate1(sPattern);

    QString ss("Apr 01");
    QRegularExpressionMatch match2;
    match2 = reDate1.match(ss,
                           0,
                           //部分匹配
                           QRegularExpression::PartialPreferCompleteMatch
                           );
    bool bHasMatched = match2.hasMatch();
    bool bPartial = match2.hasPartialMatch();
    qDebug() << bHasMatched << bPartial;

    return a.exec();
}
相关推荐
用户805533698032 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner2 天前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz7 天前
QML Hello World 入门示例
qt
xcyxiner10 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner11 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner11 天前
DicomViewer (添加模型类)3
qt
xcyxiner12 天前
DicomViewer (目录调整) 2
qt
xcyxiner12 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
LDR00614 天前
Type-C 快充全面升级!LDR6601 赋能个人护理便携电机,重塑剃须刀 / 理发器新体验
c语言·开发语言
雪碧聊技术14 天前
Tree.js是什么?一文讲透
开发语言·javascript·ecmascript