Qt的QRegExp和方法顺序

时间:2012-12-27 13:23:24

标签: regex qt

我有两个QRegExp对象,用于搜索某些文本的开头和结尾。我的代码看起来像:

// strText defined earlier
QRegExp start(...);
QRegExp end(...);

int iStart = start.indexIn(strText);
int iEnd = end.indexIn(strText, iStart) + end.matchedLength();

我对此代码有两个问题:

(1)假设找到了每个正则表达式正在寻找的文本。调用上面的代码会在运行时调用以下错误:

  

TerminalWindow.exe中0x66b48b3f处的未处理异常:0xC0000005:访问冲突读取位置0x00000004。

如果我将代码改为:

,我会得到同样的错误
int iStart = start.indexIn(strText);
int iTemp = end.matchedLength();
int iEnd = start.indexIn(strText, iStart) + iTemp;

第二个代码片段中的错误对我有意义,因为内部的matchesLength()可能针对尚未分配的对象运行。但是,我不明白为什么我从第一个代码片段也得到了同样的错误。在所有其他条件相同的情况下,不是从左到右的操作顺序?如果我将代码更改为以下内容,那么我会得到我期望的结果:

// strText defined earlier
QRegExp start(...);
QRegExp end(...);

int iStart = start.indexIn(strText);
int iEnd = end.indexIn(strText, iStart);
iEnd += end.matchedLength();

(2)如果我的示例中的strText看起来像:

<start>
  stackoverflow is awesome!
</start>
<start>
  I like cake!
</start>
<start>
  Girls are pretty!
</start>

如何编写将捕获每个start元素内容的Qt RegExp?类似的东西:

QRegExp reg("<start>(.*?)</start>");

永远不会对我有用,即使它似乎应该与POSIX正则表达式一起使用(这是我认为Qt实现的)。 (注意:我知道理想的方法是使用XML / HTML解析器(我实际上是解析HTML),但我现在对正则表达式解决方案很感兴趣。)

谢谢!

2 个答案:

答案 0 :(得分:0)

<>需要转义。尝试:

QRegExp reg("\<start\>(.*?)\</start\>");

答案 1 :(得分:0)

我无法使用您的第一个代码段重现该问题。它在我的Ubuntu盒子上对我很好。

就你的正则表达而言,存在一些问题。首先,您正在使用?以使您的正则表达式非贪婪,但它不适用于Qt。相反,您必须调用QRegExp.setMinimal(bool)方法。引用QRegExp reference docs

  

非贪婪匹配不能应用于单个量词,但是   可以应用于模式中的所有量词

如果您的字符串类似于:

'<root>\n<start>\nSo is awesome!\n</start>\n<start>\nI like cake!\n</start>\n</root>'

然后以下正则表达式将正常工作(在我的Ubuntu盒子上测试PyQt版本):

QRegExp rx("<start>\n(.*)\n</start>");
rx.setMinimal(true);

现在你所要做的就是循环如下(不完全确定它,我不是C ++人):

QStringList list;
int pos = 0;  
while ((pos = rx.indexIn(str, pos)) != -1) {
    list << rx.cap(1);
    pos += rx.matchedLength();
}

我看到的第二个问题是,正如你在问题中所说的那样,正则表达式不应该用于此任务。 Qt提供了QtXml模块,其中包含许多用于处理XML数据的类。

在你的情况下,你有一种可能性就是使用QDomDocument类。以下PyQt代码显示了如何执行此操作:

from PyQt4.QtXml import QDomDocument

mydata = "<root><start>\nSo is awesome!\n</start>\n<start>\nI like cake!\n</start><start>\nI like girls!\n</start></root>"
document = QDomDocument()
document.setContent(mydata)
root = document.documentElement()
element = root.firstChildElement("start")
while (not element.isNull()):
    value = element.firstChild().nodeValue()
    element = element.nextSiblingElement("start")
    print value

我确信如果你尝试的话,你可以很容易地将它转换为Qt代码。