项目场景:
使用Qt中的正则表达式对象QRegExp和QRegularExpression中一个bug的利用方法
问题描述:
Qt中旧版的QRegExp对象在Qt 5.x版本中已经由QRegularExpression对象替代,而且因为QRegExp对象维护不足而有一些奇怪的bug,示例代码如下:
#include <QCoreApplication>
#include <QDebug>
#include <QRegExp>
#include <QRegularExpression>
int main(int argc, char *argv[]) {
QCoreApplication a(argc, argv);
QRegExp re0("[\\x4e00-\\x9fa5\\s]");
QRegularExpression re1("[\\x4e00-\\x9fa5\\s]");
QString string("This is a 中文 sentance");
for (auto item : string.split(re0).toVector()) {
if (item.length() != 0) {
qDebug() << item << endl;
}
}
for (auto item : string.split(re1).toVector()) {
if (item.length() != 0) {
qDebug() << item << endl;
}
}
return 0;
}
预计的输出是:
This
is
a
santence
This
is
a
santence
而实际的输出是:
This
is
a
santence
中文
原因分析:
这里尝试看源代码,但是Qt中找不到这部分的实现代码,只提供了函数的原型,因此无法进行原因分析。
解决方案:
这个bug不用解决。使用的时候可以将同一个字符串使用两种正则表达式作为参数,使用QString.split()方法,QRegExp对象只会保存英文单词,QRegularExpression只会保存中文单词,因此可以用这个bug将文本中的中英文单词分开。
注:这样做在文件比较小的时候可以正常使用,在文本长度过大的时候因为调用两次split方法而会造成性能浪费。
更新: 2021-01-20
这里识别中英文是依靠十六进制码进行判断的,如果使用[\u4e00-\u9fa5]作为正则表达式那么这种方法就会失效。