2013-10-08 2 views
0

Я пытаюсь извлечь текст из квадратных скобок в строке текста. Я уже некоторое время возился с регулярным выражением и не могу получить то, что мне нужно. (Я даже не могу объяснить, почему вывод является тем, чем он является). Вот код: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:[email protected]:5060>' failed for '192.187.100.170' - No matching peer found 

И выход:

Captured texts: (".") 
timestamp cap: "." 
timestamp cap: "" 
timestamp cap: "" 
  1. Может кто-нибудь объяснить, что происходит? Почему возвращается колпачок "." когда такого символа не существует между квадратными скобками
  2. Может ли кто-то исправить регулярное выражение, чтобы извлечь временную метку из квадратных скобок?
+0

Попробуйте "\\\ [(. *) \\\]" –

ответ

3

Вам не хватает двух вещей. Сбрасывание обратной косой черты и использование setMinimal. Смотри ниже.

QString line = "messages:[2013-10-08 09:13:41] NOTICE[2366] chan_sip.c: Registration from '\"xx000 <sip:[email protected]: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: "" 

UPDATE: Что происходит:

A слэш в исходном тексте кода ++ указывает на то, что следующий символ является маскирующим, такие как \n. Чтобы иметь обратную косую черту в регулярном выражении, вам нужно избегать обратной косой черты: \\ Это сделает так, что механизм регулярного выражения видит \, как то, что будет использовать Ruby, Perl или Python.

Квадратные скобки также должны быть экранированы, поскольку они используются для обозначения диапазона элементов, обычно используемых в регулярном выражении.

Таким образом, для выражений Regular, чтобы увидеть квадратную скобку характер вам необходимо отправить его

\[ 

но C++ исходный файл не может получить \ символ в строку без двух из них в ряд поэтому он превращается в

\\[ 

Обучаясь регулярное выражение, мне понравилось, используя этот regex tool by GSkinner. У него есть листинг с правой стороны страницы уникальных кодов и символов.

QRegEx не соответствует регулярному выражению точно. Если вы изучите документацию, вы найдете много мелочей. Например, как это делает Greedy v. 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 

Надежда, что помогает.

+0

Зачем мне нужно удвоить escape [символ? Кроме того, не следует закрывать (2) возвращение второго матча [2366]? – TSG

+0

См. Обновление, которое я поставил выше. – phyatt