QRegExp未按预期提取文本

时间:2013-10-08 21:00:00

标签: regex qt qregexp

我正在尝试从一行文本的方括号中提取文本。我一直在搞乱正则表达式一段时间,而且无法得到我需要的东西。 (我甚至无法解释为什么输出是这样的)。这是代码:

QRegExp rx_timestamp("\[(.*?)\]");
int pos = rx_timestamp.indexIn(line);
if (pos > -1) {
    qDebug() << "Captured texts: " << rx_timestamp.capturedTexts();
    qDebug() << "timestamp cap: " <<rx_timestamp.cap(0);
    qDebug() << "timestamp cap: " <<rx_timestamp.cap(1);
    qDebug() << "timestamp cap: " <<rx_timestamp.cap(2);
} else qDebug() << "No indexin";

输入行是:

messages:[2013-10-08 09:13:41] NOTICE[2366] chan_sip.c: Registration from '"xx000 <sip:xx000@183.229.164.42:5060>' failed for '192.187.100.170' - No matching peer found

输出是:

Captured texts:  (".") 
timestamp cap:  "." 
timestamp cap:  "" 
timestamp cap:  "" 
  1. 有人可以解释发生了什么吗?为什么上限回归“。”当方括号之间不存在这样的字符时
  2. 有人可以更正正则表达式从方括号之间提取时间戳吗?

1 个答案:

答案 0 :(得分:3)

你错过了两件事。转义反斜杠,并使用setMinimal。见下文。

QString line = "messages:[2013-10-08 09:13:41] NOTICE[2366] chan_sip.c: Registration from '\"xx000 <sip:xx000@183.229.164.42:5060>' failed for '192.187.100.170' - No matching peer found";

QRegExp rx_timestamp("\\[(.*)\\]");
rx_timestamp.setMinimal(true);
int pos = rx_timestamp.indexIn(line);
if (pos > -1) {
    qDebug() << "Captured texts: " << rx_timestamp.capturedTexts();
    qDebug() << "timestamp cap: " <<rx_timestamp.cap(0);
    qDebug() << "timestamp cap: " <<rx_timestamp.cap(1);
    qDebug() << "timestamp cap: " <<rx_timestamp.cap(2);
} else qDebug() << "No indexin";

输出:

Captured texts:  ("[2013-10-08 09:13:41]", "2013-10-08 09:13:41") 
timestamp cap:  "[2013-10-08 09:13:41]" 
timestamp cap:  "2013-10-08 09:13:41" 
timestamp cap:  "" 

更新:发生了什么:

c ++源代码中的反斜杠表示下一个字符是转义字符,例如\n。要在正则表达式中显示反斜杠,您必须转义反斜杠,如下所示:\\这将使正则表达式引擎看到\,就像Ruby,Perl或Python将使用的那样。

方括号也应该被转义,因为它们通常用于表示正则表达式中的一系列元素。

因此,对于正则表达式引擎,您需要发送方括号字符

\[

但是c ++源文件无法将\字符放入一个字符串中,而连续两行中没有它们会变成

\\[

在学习正则表达式时,我喜欢使用此regex tool by GSkinner。它在页面右侧列出了唯一的代码和字符。

QRegEx与正则表达式完全匹配。如果你研究文档,你会发现很多小事。比如Greedy与Lazy匹配的方式。

QRegExp and double-quoted text for QSyntaxHighlighter

就我从正则表达式解析器中看到的那样,如何列出捕获是非常典型的。捕获列表首先列出所有这些列表,然后列出第一个捕获组(或第一组括号所包含的内容。

http://qt-project.org/doc/qt-5.0/qtcore/qregexp.html#cap

http://qt-project.org/doc/qt-5.0/qtcore/qregexp.html#capturedTexts

要查找更多匹配项,您必须反复调用indexIn

http://qt-project.org/doc/qt-5.0/qtcore/qregexp.html#indexIn

QString str = "offsets: 1.23 .50 71.00 6.00";
QRegExp rx("\\d*\\.\\d+");    // primitive floating point matching
int count = 0;
int pos = 0;
while ((pos = rx.indexIn(str, pos)) != -1) {
    ++count;
    pos += rx.matchedLength();
}
// pos will be 9, 14, 18 and finally 24; count will end up as 4

希望有所帮助。