首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >QT C++ QRegularExpression多重匹配

QT C++ QRegularExpression多重匹配
EN

Stack Overflow用户
提问于 2014-03-18 19:58:13
回答 2查看 9.2K关注 0票数 6

我希望使用正则表达式从QString (.html)中提取信息。我明确地希望使用Regex (无解析解决方案)和类QRegularExpression (出于几个原因,例如:原因)。

对于简化方面,这里是一个问题等价的任务。

构造的源字符串:

代码语言:javascript
复制
<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.

代码语言:javascript
复制
QRegularExpression reA(".*<bar [es]>(.*)</bar>.*", QRegularExpression::DotMatchesEverythingOption);

->

代码语言:javascript
复制
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>INFOd

2.

代码语言:javascript
复制
QRegularExpression reA("(.*<bar [es]>(.*)</bar>.*)*", QRegularExpression::DotMatchesEverythingOption);

->senseless

问题: Regex总是与整个字符串相关。<bar s>INFO</bar><bar s>INFO</bar>将选择第一个<bar s>和最后一个</bar>。通缉第一

对于QRegExp,似乎有一个解决方案,但我想用QRegularExpression来解决这个问题。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-03-18 23:19:14

也许你可以试试这个

代码语言:javascript
复制
QRegularExpression reA("(<bar [se]>[^<]+</bar>)");

QRegularExpressionMatchIterator i = reA.globalMatch(input);
while (i.hasNext()) {
    QRegularExpressionMatch match = i.next();
    if (match.hasMatch()) {
         qDebug() << match.captured(0);
    }
}

给了我这个输出

代码语言:javascript
复制
"<bar s>INFO1.1</bar>" 
"<bar e>INFO1.2
</bar>" 
"<bar s>INFO2.1</bar>" 
"<bar e>INFO2.2</bar>"  

而这句话

代码语言:javascript
复制
QRegularExpression reA("((?<=<bar [se]>)((?!</bar>).)+(?=</bar>))",
                       QRegularExpression::DotMatchesEverythingOption);

有了这个输入

代码语言:javascript
复制
<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>

作为输出给我

代码语言:javascript
复制
"INFO1</lol>.1" 
"INFO1.2
" 
"INFO2.1" 
"INFO2.2"
票数 10
EN

Stack Overflow用户

发布于 2017-04-05 20:56:09

我添加了一个新的类似的答案,这是因为缺乏处理所有指定的捕获组(而不是名称)的QRegularExpression答案。我只想能够指定捕获组,只得到那些结果,而不是整个厨房水槽。当盲目抓取捕获组0时,这就成了一个问题,几乎所有的答案都是如此,对于具有多个结果的QRegularExpression来说也是如此。此答案将返回列表中所有指定的捕获组,如果未指定捕获组,则返回捕获-组0,用于整个正则表达式匹配。

我在Gist上做了这个简化的代码片段,它没有直接解决这个问题。下面的示例应用程序,如果一个差异确实解决了这个特定的问题。

代码语言:javascript
复制
#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;
}

控制台中的输出:

代码语言:javascript
复制
 INFO1.1
 INFO2.1
 INFO2.2

对我来说,使用QRegularExpression处理正则表达式的痛苦要比std::regex的少,但它们都相当通用和健壮,需要更好的优化结果处理。我总是使用我为QRegularExpression制作的包装器来快速生成我通常想要利用的正则表达式和结果。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22489723

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档