我希望使用正则表达式从QString (.html)中提取信息。我明确地希望使用Regex (无解析解决方案)和类QRegularExpression (出于几个原因,例如:原因)。
对于简化方面,这里是一个问题等价的任务。
构造的源字符串:
<foo><bar s>INFO1.1</bar> </ qux> <peter></peter><bar e>INFO1.2
</bar><fred></ senseless></fred></ xx><lol></lol></foo><bar s>INFO2.1</bar>
</ nothing><endlessSenselessTags></endlessSenselessTags><rofl>
<bar e>INFO2.2</bar></rofl>*注:*可能有或多或少的信息和额外的无传感器标签。(6个资料来源)
通缉:
Info1.1和Info1.2以及Info2.1和Info2.2 (例如在列表中)
尝试
1.
QRegularExpression reA(".*<bar [es]>(.*)</bar>.*", QRegularExpression::DotMatchesEverythingOption);->
INFOa</bar> </ qux> <peter></peter><bar e>INFOb
</bar><fred></ senseless></fred></ xx><lol></lol></foo><bar s>INFOc</bar>
</ nothing><endlessSenselessTags></endlessSenselessTags><rofl>
<bar e>INFOd2.
QRegularExpression reA("(.*<bar [es]>(.*)</bar>.*)*", QRegularExpression::DotMatchesEverythingOption);->senseless
问题: Regex总是与整个字符串相关。<bar s>INFO</bar><bar s>INFO</bar>将选择第一个<bar s>和最后一个</bar>。通缉第一
对于QRegExp,似乎有一个解决方案,但我想用QRegularExpression来解决这个问题。
发布于 2014-03-18 23:19:14
也许你可以试试这个
QRegularExpression reA("(<bar [se]>[^<]+</bar>)");
QRegularExpressionMatchIterator i = reA.globalMatch(input);
while (i.hasNext()) {
QRegularExpressionMatch match = i.next();
if (match.hasMatch()) {
qDebug() << match.captured(0);
}
}给了我这个输出
"<bar s>INFO1.1</bar>"
"<bar e>INFO1.2
</bar>"
"<bar s>INFO2.1</bar>"
"<bar e>INFO2.2</bar>" 而这句话
QRegularExpression reA("((?<=<bar [se]>)((?!</bar>).)+(?=</bar>))",
QRegularExpression::DotMatchesEverythingOption);有了这个输入
<foo><bar s>INFO1</lol>.1</bar> </ qux> <peter></peter><bar e>INFO1.2
</bar><fred></ senseless></fred></ xx><lol></lol></foo><bar s>INFO2.1</bar>
</ nothing><endlessSenselessTags></endlessSenselessTags><rofl>
<bar e>INFO2.2</bar></rofl>作为输出给我
"INFO1</lol>.1"
"INFO1.2
"
"INFO2.1"
"INFO2.2"发布于 2017-04-05 20:56:09
我添加了一个新的类似的答案,这是因为缺乏处理所有指定的捕获组(而不是名称)的QRegularExpression答案。我只想能够指定捕获组,只得到那些结果,而不是整个厨房水槽。当盲目抓取捕获组0时,这就成了一个问题,几乎所有的答案都是如此,对于具有多个结果的QRegularExpression来说也是如此。此答案将返回列表中所有指定的捕获组,如果未指定捕获组,则返回捕获-组0,用于整个正则表达式匹配。
我在Gist上做了这个简化的代码片段,它没有直接解决这个问题。下面的示例应用程序,如果一个差异确实解决了这个特定的问题。
#include <QCoreApplication>
#include <QRegularExpressionMatch>
#include <QStringList>
#include <iostream>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QStringList results;
QRegularExpression this_regex("<bar \\w>(.*?)</bar>");
QString test_string = "<foo><bar s>INFO1.1</bar> </ qux> <peter></peter><bar e>INFO1.2\n\
</bar><fred></ senseless></fred></ xx><lol></lol></foo><bar s>INFO2.1</bar>\n\
</ nothing><endlessSenselessTags></endlessSenselessTags><rofl>\n\
<bar e>INFO2.2</bar></rofl>\n";
if(!this_regex.isValid())
{
std::cerr << "Invalid regex pattern: " << this_regex.pattern().toStdString() << std::endl;
return -2;
}
for (int i = 0; i < this_regex.captureCount()+1; ++i)
{
// This skips storing capture-group 0 if any capture-groups were actually specified.
// If they weren't, capture-group 0 will be the only thing returned.
if((i!=0) || this_regex.captureCount() < 1)
{
QRegularExpressionMatchIterator iterator = this_regex.globalMatch(test_string);
while (iterator.hasNext())
{
QRegularExpressionMatch match = iterator.next();
QString matched = match.captured(i);
// Remove this if-check if you want to keep zero-length results
if(matched.length() > 0){results << matched;}
}
}
}
if(results.length()==0){return -1;}
for(int i = 0; i < results.length(); i++)
{
std::cout << results.at(i).toStdString() << std::endl;
}
return 0;
}控制台中的输出:
INFO1.1
INFO2.1
INFO2.2对我来说,使用QRegularExpression处理正则表达式的痛苦要比std::regex的少,但它们都相当通用和健壮,需要更好的优化结果处理。我总是使用我为QRegularExpression制作的包装器来快速生成我通常想要利用的正则表达式和结果。
https://stackoverflow.com/questions/22489723
复制相似问题