2015-08-31 4 views
3

Я написал небольшую функцию для проверки шаблона через регулярное выражение в C++. Используя любой онлайн-тестер регулярных выражений, я получаю поведение, которое я ожидал бы от регулярного выражения, которое я написал, но мой код на C++ заканчивается бесконечным циклом. Вот код:regex_match() && regex_search() бесконечный цикл

#include <string> 
#include <regex> 

bool check(const std::string& val, const std::string& sep) { 
    const static std::string REGEX_STR("^.{1,}=.{1,}(" + sep + ".{1,})*$"); 
    const static std::regex REGEX(REGEX_STR); 

    std::smatch match; 
    //this end up in an infinite loop 
    return (std::regex_search(val, match, REGEX) && match.size() > 0); 

    //this also end up in an infinite loop 
    return std::regex_match(val, REGEX); 
} 

Может кто-нибудь объяснить мне почему? Как я могу исправить эту проблему?

Я разрабатываю на MS Visual Studio 2015 Enterprise версии 14.

+4

Каковы значения для 'val' и' sep'? – NathanOliver

+3

(OT: '+' не подходит для '{1,}'.) – Biffen

+2

заменить '^. {1,} =' на '^ [^ =] {1,} =' или '^ [^ =] + = ', и если это возможно:'. {1,} ('с' [^ "+ sep +"] + ('. Таким образом, вы избежите многого возврата. –

ответ

3

Проблемы с регулярным выражением, которая включает в себя большое количество возвратов шагов, чтобы закончить. Использование . (которое соответствует любому символу, но символу новой строки) не рекомендуется в случае, если строка каким-то образом разделена.

Я предлагаю использовать

const static std::string REGEX_STR("^[^=]+=[^" + sep + "]+(" + sep + "[^" + sep + "]+)*$"); 

С ; передается в качестве разделителя, он будет выглядеть ^[^=]+=[^;]+(;[^;]+)*$ и разобрать строку гораздо более эффективно (11 шагов), чем ^.{1,}=.{1,}(;.{1,})*$ (18 шагов). Представьте, что вы работаете с большим количеством данных, и будет ясно, что catastrophic backtracking произойдет быстрее.

+0

Большое вам спасибо!Ваш ответ решил мою проблему и позволяет мне понять, почему мое регулярное выражение неэффективно. Остается открыть вопрос о том, является ли он верным бесконечным циклом или нет в VS2015. –

+0

Возможно, вы можете найти ключ к [Visual Studio 2015 RTM] (https://www.visualstudio.com/en-us/news/vs2015-vs .aspx # C++) Веб-страница ... –

+1

Катастрофическое обратное отслеживание происходит из-за '.' может совпадать ';' Сложность увеличивается экспоненциально по отношению к числу ';' во входной строке. – nhahtdh

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