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();
它匹配后跟冒号或单词的有效键。如果是键,则将当前列表更改为对应的列表。否则将单词添加到当前列表中。
最后,您将拥有列表classification
、range
和integrity
,其中包含相应键之后的单词。你可以在全场比赛结束后加入他们:
QString classificationString = classification.join(" ");
但它并不关心键的顺序。
【讨论】:
【参考方案2】:还有 QRegExp::RegExp2 从 4.2 开始支持贪婪量词
【讨论】:
以上是关于QRegexp 特质(与 perl 相比):如何在没有惰性量词的情况下编写此正则表达式?的主要内容,如果未能解决你的问题,请参考以下文章
Qt 正则表达式 用QRegularExpression代替QRegExp