2

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

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

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

^begin\n([\s\S]+?)^end

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

下面是一些可用于演示我的问题的代码。对我来说,它爆炸了 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"(^begin\n([\s\S]+?)^end)", QRegularExpression::MultilineOption);
qDebug() << "start check:";
for (int i=10000; i<200000; i=i+1000) {
    QString test = "begin\n" + s.repeated(i) + "end\n";
    QRegularExpressionMatch match = re.match(test);
    if (!match.hasMatch()) {
        qDebug() << "lazy match failed - trying greedy match";
        re.setPattern(R"(^begin\n([\s\S]+)^end)");
        QRegularExpressionMatch match = re.match(test);
        qDebug() << match.hasMatch();
        break;
    }
    qDebug() << i;
}
4

1 回答 1

0

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

PCRE2 库允许MATCH_LIMIT覆盖变量以进行搜索,但此功能未在QRegularExpression. 我可以修补 Qt 库或更改 PCRE2 库默认值并重新构建,但现在我已经找到了一个基于这里的一篇好文章的替代(并且更难理解)正则表达式:

^begin\n((?:[^\n]++|\n(?!end))*+)\nend
于 2018-10-26T04:35:10.217 回答