QRegexp 特质(与 perl 相比):如何在没有惰性量词的情况下编写此正则表达式?

Posted

技术标签:

【中文标题】QRegexp 特质(与 perl 相比):如何在没有惰性量词的情况下编写此正则表达式?【英文标题】:QRegexp idiosyncracies (compared to perl): How can I write this regexp without the lazy quantifier? 【发布时间】:2009-10-16 16:40:11 【问题描述】:

我有以下在 perl 中可以正常工作的正则表达式:

Classification:\s([^\n]+?)(?:\sRange:\s([^\n]+?))*(?:\sStructural Integrity:\s([^\n]+))*\n

这个字符串应该匹配的数据格式类型是:

Classification: Class Name     Range: xxxx     Structural Integrity: value
Classification: Class Name    Structural Integrity: value
Classification: Class Name

即:“范围”和“结构完整性”字段是可选的。所以想要的结果是:


$& [Classification: Class Name Range: xxxx Structural Integrity: value ]
$1 [Class Name ]
$2 [xxxx ]
$3 [value ]

$& [Classification: Class Name    Structural Integrity: value ]
$1 [Class Name ]
$2 [value ]

$& [Classification: Class Name ]
$1 [Class Name ]

表达式使用 ?两个地方的惰性量词。 QRegExp 不支持此运算符,而是 Qt 使用“最小”属性,当设置为 true 时,使表达式中的 all 量词非贪婪

有了这些信息,我编写了我的代码:

QRegExp rx("Classification:\\s([^\\n]+)(?:\\sRange:\\s([^\\n]+))*(?:\\sStructural Integrity:\\s([^\\n]+))*\\n");
rx.setMinimal(true);

但结果不正确,经过多次调整,我无法获得正确的捕获。是否可以将其拆分为更多代码和更少的正则表达式?还是在没有惰性运算符的情况下重写它?

【问题讨论】:

不,不是星际迷航……但它与空间有关;) 【参考方案1】:

类似这样的:

QRegExp rx("(Classification|Range|Structural\\s+Integrity):|(\\S+)");
QStringList classification();
QStringList range();
QStringList integrity();

QStringList current = null;

int pos;
while ((pos = rx.indexIn(str, pos)) != -1) 
    if (rx.cap(1) == null) 
        if (current != null) 
            current << rx.cap(2);
        
    
    else if ("Classification".equals(rx.cap(1))) 
       current = classification;
    
    else if ("Range".equals(rx.cap(1))) 
       current = range;
    
    else if ("Structural Integrity".equals(rx.cap(1))) 
       current = integrity;
    
    pos += rx.matchedLength();

它匹配后跟冒号或单词的有效键。如果是键,则将当前列表更改为对应的列表。否则将单词添加到当前列表中。

最后,您将拥有列表classificationrangeintegrity,其中包含相应键之后的单词。你可以在全场比赛结束后加入他们:

QString classificationString = classification.join(" ");

但它并不关心键的顺序。

【讨论】:

【参考方案2】:

还有 QRegExp::RegExp2 从 4.2 开始支持贪婪量词

【讨论】:

以上是关于QRegexp 特质(与 perl 相比):如何在没有惰性量词的情况下编写此正则表达式?的主要内容,如果未能解决你的问题,请参考以下文章

Qt 正则表达式 用QRegularExpression代替QRegExp

如何使用 QRegExp grep 进程的最后一行输出?

QRegExp::pos() 没有相应的 QRegExp::len() 有啥用?

Qt官方示例-正则测试工具

Scala入门2(特质与叠加在一起的特质)

我可以告诉 Perl 一些数据是不可变的以加快速度吗?