Qt / QRegularExpression - 无法捕获所有结果,只有第一个实例,为什么?
Qt / QRegularExpression - Can't capture all results, only 1st instance, why?
我正在尝试让一些文本被 <td>
标签包围。我的问题是我只能获取第一个结果,而不能获取其他结果。
从下面的 HTML 中,我只得到第一个结果,即这段文字:
Student Name
但是所有其他捕获所需文本其余部分的尝试都是空的,无效的。为什么会这样?我做错了什么?
用于正则表达式的文本:
<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 所称的 global 正则表达式 flag/modifier,这意味着,在找到第一个匹配项后继续查找匹配项。
为了使用 QT 做到这一点,请尝试使用 globalMatch() versus match()。
前者会 return 一个 QRegularExpressionIterator,你可以迭代它来找到你所有的匹配项。
另外,<td>(.*)</td>
中的*是贪心的,所以将找到 <td>
的第一个实例,然后尽可能多地捕获 (包括您的大部分内容和其他 <td>
标签),只要能在最后找到一个</td>
.
有多种方法可以避免这种情况。一种方法是使用<td>(.*?)</td>
,它会尽可能地捕获小,只要它能找到一个</td>
最后。只要没有进一步嵌套的另一个 <td />
,这基本上会捕获单个 <td />
标记中的所有内容在(在您的场景中看起来不是这种情况)。
另外,此处不需要 QRegularExpression::MultilineOption PatternOption,因为它属于正则表达式字符 ^ 和 $,您没有使用它。
您可能对 QRegularExpression::DotMatchesEverythingOption PatternOption 感兴趣,它包括点中的换行符,以防万一 <td />
标签或其中包含的值恰好跨越多行
...全局匹配可用于查找主题字符串中给定正则表达式的所有出现...
QRegularExpressionMatchIterator i = regex.globalMatch(resultHTML);
while (i.hasNext())
{
QRegularExpressionMatch match = i.next();
qDebug() << match.captured();
}
我正在尝试让一些文本被 <td>
标签包围。我的问题是我只能获取第一个结果,而不能获取其他结果。
从下面的 HTML 中,我只得到第一个结果,即这段文字:
Student Name
但是所有其他捕获所需文本其余部分的尝试都是空的,无效的。为什么会这样?我做错了什么?
用于正则表达式的文本:
<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 所称的 global 正则表达式 flag/modifier,这意味着,在找到第一个匹配项后继续查找匹配项。
为了使用 QT 做到这一点,请尝试使用 globalMatch() versus match()。
前者会 return 一个 QRegularExpressionIterator,你可以迭代它来找到你所有的匹配项。
另外,<td>(.*)</td>
中的*是贪心的,所以将找到 <td>
的第一个实例,然后尽可能多地捕获 (包括您的大部分内容和其他 <td>
标签),只要能在最后找到一个</td>
.
有多种方法可以避免这种情况。一种方法是使用<td>(.*?)</td>
,它会尽可能地捕获小,只要它能找到一个</td>
最后。只要没有进一步嵌套的另一个 <td />
,这基本上会捕获单个 <td />
标记中的所有内容在(在您的场景中看起来不是这种情况)。
另外,此处不需要 QRegularExpression::MultilineOption PatternOption,因为它属于正则表达式字符 ^ 和 $,您没有使用它。
您可能对 QRegularExpression::DotMatchesEverythingOption PatternOption 感兴趣,它包括点中的换行符,以防万一 <td />
标签或其中包含的值恰好跨越多行
...全局匹配可用于查找主题字符串中给定正则表达式的所有出现...
QRegularExpressionMatchIterator i = regex.globalMatch(resultHTML);
while (i.hasNext())
{
QRegularExpressionMatch match = i.next();
qDebug() << match.captured();
}