2016-04-13 6 views
1

Я пытаюсь сделать regex_match на строке, которая имеет квадратные скобки ([]) внутри нее.regex_match для квадратных скобок

Вещи, которые я пробовал до сих пор:

. Нормальное совпадение.

. По спине, сокращая квадратные скобки на 1 косую черту.

. По спине сбрасывая квадратные скобки на 2 слэша.

// regex_match example 
#include <iostream> 
#include <cstring> 
#include <regex> 

using namespace std; 

int main() { 
    std::string str1 = "a/b/c[2]/d"; 
    std::string str2 = "(.*)a/b/c[2]/d(.*)"; 
    std::regex e(str2); 

    std::cout << "str1 = " << str1 << std::endl; 
    std::cout << "str2 = " << str2 << std::endl; 
    if (regex_match(str1, e)) { 
    std::cout << "matched" << std::endl; 
    } 
} 

Это сообщение об ошибке, которое я получаю каждый раз, когда я его компилирую.

terminate called after throwing an instance of 'std::regex_error' 
what(): regex_error 
Aborted (core dumped) 

мне сказали члены переполнение стека, что GCC 4.8 или более раннюю версию, что, как известно, глючит. Итак, мне нужно было обновить его до последней версии.

Я создал идеон в https://ideone.com/fJEKAF, где компилятор не должен выдавать (я полагаю). Даже там, я не вижу regex_match.

+0

Что такое версия GCC? –

+0

@ WiktorStribiżew, Модель модели: posix gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1) –

+1

Итак, все ответы не помогают. Просто обновите свой компилятор gcc до некоторой последней версии. –

ответ

1

Основная проблема у вас есть устаревший GCC компилятор: вы необходимо обновить до некоторой версии. 4.8.x просто не поддерживает регулярное выражение так, как должно.

Теперь код, который вы должны использовать это:

#include <iostream> 
#include <cstring> 
#include <regex> 

using namespace std; 

int main() { 
    std::string str1 = "a/b/c[2]/d"; 
    std::string str2 = R"(a/b/c\[2]/d)"; 
    std::regex e(str2); 

    std::cout << "str1 = " << str1 << std::endl; 
    std::cout << "str2 = " << str2 << std::endl; 
    if (regex_search(str1, e)) { 
     std::cout << "matched" << std::endl; 
    } 
} 

См IDEONE demo

Использование

  • regex_search вместо regex_match искать частичных совпадений (regex_match требует полное совпадение строк)
  • [2] в шаблоне регулярного выражения соответствует буквалу 2 ([...] - это класс символов, соответствующий 1 символу из диапазона/списка, указанного в классе символов). Чтобы соответствовать литеральным квадратным скобкам, вам необходимо избежать [, и вам не нужно бежать ]: R"(a/b/c\[2]/d)".
+0

где вы используете квадратные скобки в своих регулярных выражениях/строк для сравнения? То, что вы написали, просто простое и простое регулярное выражение, которое btw также работает с 4.8. –

+1

Полностью понятен после введения косой черты в вашем коде. Благодаря! –

+0

Вы можете прочитать больше о том, какие символы должны быть экранированы для механизма регулярных выражений, чтобы обрабатывать их буквально [здесь] (http://regular-expressions.info/characters.html). –

0

Ну, их обязательно следует избегать, используя обратную косую черту. К сожалению, поскольку обратная косая черта сама по себе особенна в строковой строке, вам нужны две обратные косые черты. Поэтому регулярное выражение должно выглядеть как "(.*)a/b/c\\[2\\]/d(.*)".

+0

Я боюсь сказать, что это не работает. –

+0

Перфорированные косые черты также могут быть экранированы ... '' "\\ /" '' – BitTickler

+0

@BitTickler. Нет, это не так. Напишите этот код без квадратных скобок, и он будет соответствовать. Даже с косой чертой. –

0

Сырые строковые литералы часто упрощают случаи, когда один в противном случае пришлось бы иметь сложные управляющие последовательности:

#include <iostream> 
#include <cstring> 
#include <regex> 

using namespace std; 

int main() { 
    std::string str1 = "a/b/c[2]/d"; 
    std::string str2 = R"regex((.*)a/b/c[2]/d(.*))regex"; 
    std::regex e(str2); 

    std::cout << "str1 = " << str1 << std::endl; 
    std::cout << "str2 = " << str2 << std::endl; 
    if (regex_match(str1, e)) { 
     std::cout << "matched" << std::endl; 
    } 
} 

ожидается выход:

str1 = a/b/c[2]/d 
str2 = (.*)a/b/c[2]/d(.*) 
+0

Спасибо, что написал это. Первоначально, я думал, что это хорошая идея попробовать свой код. К сожалению, это не сработало. Все еще давая мне тот же «std :: regex_error». –

+0

В шаблоне OP ничего не избежать. Ошибка, скорее всего, из-за старой версии GCC. –

+0

Модель нити: posix gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1) –

Смежные вопросы