正则表达式
正则表达式即一个文本匹配字符串的一种模式,Qt 中 QRegExp 类实现使用正则表达式进行模式匹配,且完全支持 Unicode,主要应用:字符串验证、搜索、查找替换、分割。正则表达式中字符及字符集
元素 | 含义 |
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 个反向引用 |
量词 | 含义 |
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 次 |
断言 | 含义 |
^ | 标志字符串的开始。若匹配“^”则使用“\\^” |
$ | 标志字符串的结尾。若匹配“$”则使用“\\$” |
\b | 一个单词的边界( 匹配的就是边界内的单词为一个整体 ) |
\B | 一个非单词的边界。当\b 为 false 则它为 true |
(?=E) | 表达式后紧跟 E 才匹配 |
(?!E) | 表达式后不跟 E 才匹配 |
通配符 | 含义 |
c | 任意一个字符,表字符本身 |
? | 任意一个字符,类似 regexp 中“.” |
* | 任意 0 个或多个字符 |
[...] | 在[]中的字符集 |
QRegExp reg("ab");
qDebug() << "匹配字符串本身";
qDebug() << reg.exactMatch("abc");
qDebug() << reg.exactMatch("ab");
QRegExp reg0("(\\d*\\.\\D{2})");
qDebug() << "匹配数字" << reg0.exactMatch("195.cm") << reg0.exactMatch("cm");
//设置匹配语法
QRegExp reg1("*.txt");
reg1.setPatternSyntax(QRegExp::Wildcard); //支持通配符
qDebug() << "支持通配符: " << reg1.exactMatch("当前hi.txt") << reg1.exactMatch(".txt");
//匹配单词边界
QRegExp reg2;
reg2.setPattern("\\b(hello|word)\\b");
qDebug() << "匹配到的单词的起始位置(以单词为单位):" << reg2.indexIn(" hello")
<< reg2.indexIn("wdf");
QRegExp reg3("(\\d+)(?:\\s*)(cm|icn)");
int index = reg3.indexIn("YaoMing 222 cm");
if (index > -1) {
qDebug() << "文本捕获:" << reg3.cap(0) << "cap(1): " << reg3.cap(1)
<< "cap(2): " << reg3.cap(2);
}
QRegExp reg4("面(?!包)"); //(?!):不紧跟才匹配
QString str = "吃面包,面包使用面粉做的,面粉可以做面食物";
qDebug() << str;
str.replace(reg4, "薯条");
qDebug() << str;
QRegularExpression regexp("hello");
qDebug() << "QRegularExpression匹配字符" << regexp.match("hellow");
regexp.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
qDebug() << "QRegularExpression使用大小写不敏感之后匹配字符" << regexp.match("Hellow");
QRegularExpression qData("^(\\d\\d)/(\\d\\d)/(\\d\\d\\d\\d)$");
QRegularExpressionMatch mach = qData.match("01/01/2024");
QString mach0 = mach.captured(0);
QString day = mach.captured(1);
QString month = mach.captured(2);
QString year = mach.captured(3);
if (mach.hasMatch()) {
qDebug() << "捕获的文本:" << mach0 << "天: " << day << "月: " << month << "年: " << year;
}
QString setPatten;
setPatten = "^(Jan|Fei|Mar|Apr|May) \\d\\d \\d\\d\\d\\d";
QRegularExpression Qdata(setPatten); //将字符串作为正则表达式QRegularExpressionMatch mach2
= Qdata.match("Jan 01", 0, QRegularExpression::PartialPreferCompleteMatch); //部分匹配
if (mach2.hasPartialMatch()) {
qDebug() << mach2.hasMatch() << mach2.hasPartialMatch();
}
文件处理
QFile 类用于文件操作,它提供了读写文件的接口,可以读写文件、二进制文件和 Qt 资源文件。 处理文本文件和二进制文件, 可以使用 QTextStream 类和 QDataStream 类 。处理临时文件可以使用 QTemporaryFile, 获取信息可以使用 QFileInfo,处理目录可以使用 QDir ,监视文件和目录变化可以使用 QFileSystemWatcher.
QTextStream 的流操作符
操作符 | 作用描述 |
bin | 设置读写的整数为 二进制数 |
oct | 设置读写的整数为 八进制数 |
dec | 设置读写的整数为十进制数 |
hex | 设置读写的整数为十六进制数 |
showbase | 强制显示进制前缀,如十六进制(0x)、八进制(0)、二进制(0b) |
forcesign | 强制显示符号(+、-) |
forcepoint | 强制显示小数点 |
noshowbase | 强制不显示前缀 |
noforcesign | 强制不显示符号 |
uppercasebase | 显示大写的进制前缀 |
lowercasebase | 显示小些的进制前缀 |
uppercasedigits | 用大写字母表示 |
lowercasedigits | 用小写字母表示 |
fixed | 固定小数点表示 |
scientific | 科学计数法表示 |
left | 左对齐 |
right | 右对齐 |
center | 居中 |
endl | 换行 |
flush | 清除缓冲 |
#include "QDataStream"
#include "QDate"
#include "QDebug"
#include "QFile"
QFile file;
file.setFileName("user.txt");
//读取文件
if (file.open(QIODevice::ReadOnly)) {
char buff[100];
qint32 n;
n = file.readLine(buff, sizeof(buff));
if (n != -1) {
qDebug() << "长度: " << n << "内容: " << buff;
file.close();
}
} else {
qDebug() << file.errorString();
}
//文件写入
double dPI = 3.14159;
int age = 32;
QFile file1;
file1.setFileName("data.txt");
if (file1.open(QIODevice::WriteOnly | QIODevice::Truncate)) { //覆盖
QTextStream out(&file1);
out << QString("PI: ") << qSetRealNumberPrecision(3) << right << qSetFieldWidth(10) << dPI
<< endl
<< bin << qSetFieldWidth(10) << left << age;
}
file1.close();
//二进制文件读写
QFile bininfo;
bininfo.setFileName("info.bat");
if (bininfo.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
QDataStream out(&bininfo);
out << QString("文博波") << QDate::fromString("2024-01-25", "yyyy-MM-dd") << (qint32) 25;
}
bininfo.close();
if (bininfo.open(QIODevice::ReadOnly)) {
QDataStream in(&bininfo);
QString name;
QDate time;
qint32 age;
in >> name >> time >> age;
qDebug() << name << time << age;
}
获取文件信息
#include "QDateTime"
#include "QFileDialog"
void Widget::infoFile(QString &filename)
{
QFileInfo info(filename);
qint64 size = info.size();
QDateTime createTime = info.created();
QDateTime modifyTime = info.lastModified();
QDateTime readTime = info.lastRead();bool isDic = info.isFile();
bool isDir = info.isDir();
bool isSym = info.isSymLink();
bool isread = info.isReadable();
bool isWrite = info.isWritable();
bool isHidden = info.isHidden();
bool isExcu = info.isExecutable();
ui->CreateTimeLineEdit->setText(createTime.toString());
ui->DicSizeLineEdit->setText(QString::number(size));
ui->LastReadLineEdit->setText(readTime.toString());
ui->LastModifyLineEdit->setText(modifyTime.toString());//设置属性按钮
ui->xad->setChecked(isDic);
ui->xal->setChecked(isSym);
ui->xah->setChecked(isHidden);
ui->xar->setChecked(isread);
ui->xaw->setChecked(isWrite);
ui->xae->setChecked(isExcu);
ui->xaf->setChecked(isDir);
}void Widget::on_DicFileBtn_clicked()
{
//获取文件
// QString filename = QFileDialog::getOpenFileName(this,
// "打开文件",
// "./",
// "C++(*.cpp);;"// "C (*.c);;"
// "Head file(*.h)");
//获取文件夹
QString filename = QFileDialog::getExistingDirectory(this, "获取文件", "./");
ui->DicFilelineEdit->setText(filename);
infoFile(filename); //把参数传出去
}