2016-01-21 3 views
0

Я пытаюсь получить текст, окруженный <td> тегами. Моя проблема в том, что я могу получить только первый результат и не могу получить других.Qt/QRegularExpression - Не удается зафиксировать все результаты, только 1-й экземпляр, почему?

Со следующего HTML, я получаю только 1-ый результат, который этот текст:

Имя студента

Но все остальные попытки захватить остальную часть необходимого текста являются пустыми, нуль , Почему это & что я делаю неправильно?

Текст для регулярного выражения для работы на:

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

Пожалуйста, не разобрать HTML с помощью используя регулярные выражения! – peppe

+0

@peppe Да, конечно, но при работе с небольшими объемами данных я просто предпочитаю держать его как можно проще. –

ответ

2

Вы хотите применить то, что Perl относится как к глобальной regex flag/modifier, что означает, продолжить поиск совпадений после f первая была найдена.

Чтобы сделать это с помощью QT, попробуйте использовать globalMatch() по сравнению с match().

Бывший вернет QRegularExpressionIterator, над которым вы можете выполнить итерацию, чтобы найти все ваши матчи.

Кроме, то * в <td>(.*)</td> жадные, поэтому он будет найти первый экземпляр <td>, а затем захватить как много как можно (в том числе большой части вашего контента и дополнительные <td> теги), если найдет </td> в конце.

Есть разные способы избежать этого. Один из способов заключается в использовании <td>(.*?)</td>, который бы захватить, как мало насколько это возможно, до тех пор, как он может найти </td> в конце. Это по существу захватывало бы все в пределах одного тега <td />, если не существует другого <td /> вложенное дальше внутри (что не похоже на случай вашего сценария).

Кроме, то QRegularExpression::MultilineOption PatternOption здесь не требуется, так как она относится к регулярным выражениям символов ^ и $, которые вы не используете.

Вы могли бы вместо того, чтобы быть заинтересованы в QRegularExpression :: DotMatchesEverythingOption PatternOption, который включает в себя новые строки в точках, только в случае, если эти <td /> метки, или значения, содержащиеся в, случись занимать несколько строк

2

. ..Global соответствие полезно найти все вхождения данного регулярного выражения внутри строки темы ...

QRegularExpressionMatchIterator i = regex.globalMatch(resultHTML); 

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