QRegularExpression 惰性匹配不适用于非常大的字符串



我在Qt 5.10.1中使用QRegularExpression从由页眉和页脚绑定的文件中提取文本部分。例如,请考虑以下文本:

...
begin
some text
some more text
...
end
...
begin
etc.

然后,我将使用以下正则表达式来捕获一段文本:

^beginn([sS]+?)^end

这里没有什么不寻常的。问题是,如果文本部分非常大(超过 100k 行(,则正则表达式将停止生成匹配项。我尝试在不同的文本编辑器(TextPad(中进行搜索,它工作正常,所以我怀疑这是由于QRegularExpression中的某种MAX_SIZE常量,或者更可能是它使用的PCRE2库。但我不知道去哪里看,或者这是否可以调整?或者也许这被认为是一个错误?

下面是一些可用于演示我的问题的代码。对我来说,它在 100,000 行(10,000,000 字节(处爆炸。

QString s = "This line of text is exactly one hundred bytes long becuase it's a nice round number for this test.n";
QRegularExpression re = QRegularExpression(R"(^beginn([sS]+?)^end)", QRegularExpression::MultilineOption);
qDebug() << "start check:";
for (int i=10000; i<200000; i=i+1000) {
QString test = "beginn" + s.repeated(i) + "endn";
QRegularExpressionMatch match = re.match(test);
if (!match.hasMatch()) {
qDebug() << "lazy match failed - trying greedy match";
re.setPattern(R"(^beginn([sS]+)^end)");
QRegularExpressionMatch match = re.match(test);
qDebug() << match.hasMatch();
break;
}
qDebug() << i;
}

因此,事实证明,QRegularExpression实现的 PCRE2 库有一个默认为 10,000,000 的MATCH_LIMIT变量(在库的 config.h 文件中(。这与"惰性"匹配的性质相结合(因为将搜索向前推进一个字符算作对MATCH_LIMIT的匹配(解释了我所看到的。这是不幸的,因为我认为在这个例子中惰性匹配的性能非常好。

PCRE2 库允许在搜索中覆盖MATCH_LIMIT变量,但此功能未在QRegularExpression中实现。我可以修补Qt库或更改PCRE2库默认值并重新构建,但是现在我已经根据这里的一篇好文章找到了另一种(并且更难理解(正则表达式:

^beginn((?:[^n]++|n(?!end))*+)nend

相关内容

  • 没有找到相关文章

最新更新