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

时间:2016-01-21 18:30:20

标签: c++ regex qt qregexp qregularexpression

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

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

  

学生姓名

但是所有其他捕获所需文本的其他尝试都是空的,为null。为什么那&amp;我做错了什么?

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

<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);

2 个答案:

答案 0 :(得分:2)

您希望将Perl引用的内容应用为全局正则表达式标志/修饰符,这意味着,在找到第一个匹配项后继续查找匹配项。

要使用QT执行此操作,请尝试使用globalMatch()match()

前者将返回QRegularExpressionIterator,您可以通过迭代查找所有匹配项。

另外 <td>(.*)</td> 中的 * 是贪婪的,因此它会找到 {{的第一个实例1}} ,然后尽可能多地捕获 (包括大部分内容和其他 <td> 标记),只要它能找到 <td> 最后。

有许多方法可以避免这种情况。一种方法是使用 </td> ,只要能够找到 <td>(.*?)</td> ,它就会尽可能地捕获 little 强>最后。只要没有其他 </td> 进一步嵌套(这不会)看起来就像你的情景一样。)

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

您可能会对 QRegularExpression :: DotMatchesEverythingOption PatternOption感兴趣,其中包括点的换行符,以防这些 <td /> 标记或值包含在内,碰巧跨越多行

答案 1 :(得分:2)

...全局匹配对于在主题字符串中查找给定正则表达式的所有出现次数非常有用...

QRegularExpressionMatchIterator i = regex.globalMatch(resultHTML);

while (i.hasNext()) 
{
    QRegularExpressionMatch match = i.next();        
    qDebug() << match.captured();
}