Qt / QRegularExpression - 无法捕获所有结果,只能捕获第一个实例,为什么?

Qt / QRegularExpression - Can't capture all results, only 1st instance, why?

本文关键字:第一个 为什么 实例 结果 QRegularExpression Qt      更新时间:2023-10-16

我正在尝试获取一些被<td>标签包围的文本。我的问题是我只能获取第一个结果,而无法获得其他结果。

从下面的 HTML 中,我只得到第一个结果,即此文本:

学生姓名

但是,捕获所需文本其余部分的所有其他尝试都是空的,为空。为什么会这样,我做错了什么?

正则表达式要处理的文本:

<table width="52%" border="1" align="center" cellpadding="1" cellspacing="1">
  <tr>
    <td colspan="2" align="center" bgcolor="#999999">Result</td>
    </tr>
  <tr>
    <td width="22%"><strong>Student ID</strong></td>
    <td width="78%">13/0003337/99</td>
  </tr>
  <tr>
    <td><strong>Student Name</strong></td>
    <td>Alaa Salah Yousuf Omer</td>
  </tr>
  <tr>
    <td><strong>College</strong></td>
    <td>Medicine & General Surgery</td>
  </tr>
  <tr>
    <td><strong>Subspecialty</strong></td>
    <td>General</td>
  </tr>
  <tr>
    <td><strong>Semester</strong></td>
    <td>Fourth</td>
  </tr>
  <tr>
    <td><strong>State</strong></td>
    <td>Pass</td>
  </tr>
  <tr>
    <td><strong>Semester's GPA</strong></td>
    <td>2.89</td>
  </tr>
  <tr>
    <td><strong>Overall GPA</strong></td>
    <td>3.13</td>
  </tr>
  </table>

我的代码:

QString resultHTML = "A variable containing the html code written above."
QRegularExpression regex("<td>(.*)</td>", QRegularExpression::MultilineOption);
QRegularExpressionMatch match = regex.match(resultHTML);
// I only get the 1st result logged withing debugger
for(int x = 0; x <= match.capturedLength(); x++)
{
    qDebug() << match.captured(x);
}
// This here doesn't get me anything, null!
_studentName = match.captured(2);
_semesterWritten = match.captured(8);
_stateWritten = match.captured(10);
_currentGPA = match.captured(12);
_overallGPA = match.captured(14);

你正在寻找应用Perl所说的全局正则表达式标志/修饰符,这意味着,在找到第一个匹配项后继续寻找匹配项。

为了使用 QT 做到这一点,请尝试使用 globalMatch() 与 match()。

前者将返回一个QRegularExpressionIterator,您可以在其上迭代以查找所有匹配项。

此外<td>(.*)</td>中的 * 是贪婪的,所以它会找到<td>的第一个实例,然后尽可能地捕获(包括你的大部分内容和额外的<td>标签),只要它能在最后找到一个</td>

有不同的方法可以避免这种情况。 一种方法是使用 <td>(.*?)</td> ,只要它能在最后找到</td>,它就会尽可能地捕获。 这基本上会捕获单个<td />标记中的所有内容,只要没有另一个嵌套在其中的<td />(在您的方案中看起来并非如此)。

此外,这里不需要 QRegularExpression::MultilineOption PatternOption,因为它与你不使用的正则表达式字符 ^$ 有关。

相反,您可能对QRegularExpression::D otMatchesEverythingOption PatternOption感兴趣,它包括点中的换行符,以防万一这些<td />标签或其中包含的值碰巧跨越多行

...全局匹配对于查找主题字符串中给定正则表达式的所有匹配项很有用...

QRegularExpressionMatchIterator i = regex.globalMatch(resultHTML);
while (i.hasNext()) 
{
    QRegularExpressionMatch match = i.next();        
    qDebug() << match.captured();
}
相关文章: