即使 regex101.com 匹配,QRegExp 也不匹配

Posted

技术标签:

【中文标题】即使 regex101.com 匹配,QRegExp 也不匹配【英文标题】:QRegExp does not match even though regex101.com does 【发布时间】:2016-08-15 12:59:29 【问题描述】:

我需要用简单的语法从字符串中提取一些数据。语法是这样的:

_IMPORT:<strong>[any text]</strong> - <strong>[HEX number]</strong> #<strong>[decimal number]</strong>

因此我创建了正则表达式,您可以在下面的代码中看到:

 //SYNTAX:  _IMPORT:%1 - %2 #%3
 static const QRegExp matchImportLink("^_IMPORT:(.*?) - ([A-Fa-f0-9]+) #([0-9]+)$");
 QRegExp importLink(matchImportLink);
 QString qtWtf(importLink.pattern());
 const int index = importLink.indexIn(mappingName);

 qDebug()<< "Input string: "<<mappingName;
 qDebug()<< "Regular expression:"<<qtWtf;
 qDebug()<< "Result: "<< index;

由于某种原因,这不起作用,我得到以下输出:

Input string:  "_IMPORT:ddd - 92806f0f96a6dea91c37244128f7d00f #0"
Regular expression: "^_IMPORT:(.*?) - ([A-Fa-f0-9]+) #([0-9]+)$"
Result:  -1

我什至尝试删除锚点 ^$ 但这并没有帮助,也是不受欢迎的。烦人的是,如果我复制 regex101.com 中的输出,这个正则表达式可以完美运行,如您在此处看到的:https://regex101.com/r/oT6cY3/1

谁能解释这里出了什么问题?我是否偶然发现了 Qt 错误?我使用 Qt 5.6。有什么解决方法吗?

【问题讨论】:

没有正则表达式的经验。但是IMPORT:**(** 和所有其他人之后的圆括号对我来说看起来很奇怪。 - 我希望 RegExp 匹配 (character,它不在表达式中。但是,如果他们有正则表达式语义,请忘记我的评论。 @BernhardHeinrich 他们使用(引用文档)“类似 Perl 的丰富模式匹配语法”,这意味着存在捕获组,我过去使用过它们没有问题。 我看到将(.*?) 更改为(.*) 会有所帮助,但不知道为什么。更改正则表达式引擎也无济于事...... @mike.dld 似乎他们得到了相反的方式,因为(.*?) 不贪心以防止匹配 ` - [hex]` 部分。 已经使用 QRegularExpression 了! :) QRegExp 支持非常有限的模式语法(特别是:它不支持非贪婪量词)。 QRegularExpression 支持 PCRE。 【参考方案1】:

Qt 似乎无法将限定符 *? 识别为有效。检查方法 QRegExp::isValid() 是否符合您的模式。就我而言,它因此而不起作用。并且文档告诉任何无效的模式永远不会匹配。

所以我尝试的第一件事是跳过?,它完全适合您提供的字符串与所有捕获组。这是我的代码。

QString str("_IMPORT:ddd - 92806f0f96a6dea91c37244128f7d00f #0");
QRegExp exp("^_IMPORT:(.*) - ([A-Fa-f0-9]+) #([0-9]+)$");

qDebug() << "pattern:" << exp.pattern();
qDebug() << "valid:" << exp.isValid();
int pos = 0;
while ((pos = exp.indexIn(str, pos)) != -1) 
    for (int i = 1; i <= exp.captureCount(); ++i)
        qDebug() << "pos:" << pos << "len:" << exp.matchedLength() << "val:" << exp.cap(i);
    pos += exp.matchedLength();

这是结果输出。

pattern: "^_IMPORT:(.*) - ([A-Fa-f0-9]+) #([0-9]+)$"
valid: true
pos: 0 len: 49 val: "ddd"
pos: 0 len: 49 val: "92806f0f96a6dea91c37244128f7d00f"
pos: 0 len: 49 val: "0"

使用 Qt 5.6.1 测试。

另请注意,您可以使用QRegExp::setMinimal(bool) 设置贪婪评估。

【讨论】:

非常感谢您的回答! :) 你知道这种行为是否是故意的吗? .*? 在 RegExp 中非常普遍,所以我发现它无效令人惊讶...... 看看QRegularExpression

以上是关于即使 regex101.com 匹配,QRegExp 也不匹配的主要内容,如果未能解决你的问题,请参考以下文章

Regex.Replace 替换空匹配

正则辅助工具

第一个正则表达式实例匹配在第一行不匹配?

为啥这个正则表达式模式不匹配? [复制]

正则表达式适用于 regex101.com,但不适用于 prod

正则表达式适用于 regex101.com,但不适用于 prod