Проверяю строку состоящую из 10000 a и одного b на соответствие регулярному выражению a*b , regex_match возвращает true. Заменяю выражение на (a)*b , в regex_match бросает исключение runtime_error. Смотрю, оказывается происходит переполнение стека. Замена (a)*b на (?:a)*b не помогает. Как же быть, если нужно записать что-то вроде (a|c)*b ?
int main()
{
int const n = 10000;
char s[n];
std::fill_n(s, n, 'a');
s[n] = 'b';
s[n + 1] = '\0';
boost::regex e("(?:a)*b");
bool b = boost::regex_match(s, e);
return 0;
}
22.04.08 02:12: Перенесено модератором из 'C/C++' — Кодт
Здравствуйте, igna, Вы писали:
I>Проверяю строку состоящую из 10000 a и одного b на соответствие регулярному выражению a*b , regex_match возвращает true. Заменяю выражение на (a)*b , в regex_match бросает исключение runtime_error. Смотрю, оказывается происходит переполнение стека. Замена (a)*b на (?:a)*b не помогает. Как же быть, если нужно записать что-то вроде (a|c)*b ?
попробуй
"(?:a|c)*b"
"[ac]*b"
Здравствуйте, igna, Вы писали:
I>Проверяю строку состоящую из 10000 a и одного b на соответствие регулярному выражению a*b , regex_match возвращает true. Заменяю выражение на (a)*b , в regex_match бросает исключение runtime_error. Смотрю, оказывается происходит переполнение стека. Замена (a)*b на (?:a)*b не помогает. Как же быть, если нужно записать что-то вроде (a|c)*b ?
I>
I>int main()
I>{
I> int const n = 10000;
I> char s[n];
I>}
I>
ну, вообще-то у тебя стек может исчерпаться уже вот здесь.
тебе обязательно нужно такой здоровенный массив держать на стеке?
Попробуй смеху ради вынести его за пределы функции, или превратить в std::vector — исправится положение?
З.Ы. у меня на 64-битной машине твой код сработал без проблем
Здравствуйте, igna, Вы писали:
I>Проверяю строку состоящую из 10000 a и одного b на соответствие регулярному выражению a*b , regex_match возвращает true. Заменяю выражение на (a)*b , в regex_match бросает исключение runtime_error. Смотрю, оказывается происходит переполнение стека. Замена (a)*b на (?:a)*b не помогает. Как же быть, если нужно записать что-то вроде (a|c)*b ?
I>non-stack recursive matching algorithm ... always safe no matter how pathological the regular expression
I>Спасибо. Попробую для моего "патологического" выражения (a|cd)*b .
I>Хотя стек-не стек, работы для regex_match выражение (a)*b или (?:a)*b задает похоже значительно больше. Хотелось бы понять, почему.
Ну, почему первое — понятно, это же capturing-скобки (как по-русски это будет, есть термин?), а вот со вторым — действительно непонятно, должно быть то же самое, что из без скобок вообще.
У тебя какая версия буста, кстати?
Попробуй последнюю, если сработает, значит, был баг и его пофиксили.
Здравствуйте, jazzer, Вы писали:
J>У тебя какая версия буста, кстати? J>Попробуй последнюю, если сработает, значит, был баг и его пофиксили.
1.34.1, то есть почти самая последняя. Зато VC++ 6.0.
Если это баг в Boost.Regex, то это странно. На ровном месте ведь. Я в регулярных выражениях новичок и надеялся, что я сам что-нибудь неправильно сделал. Например, что нужно не (a)*b , а ^(a)*b$ или (a)*?b .
Здравствуйте, igna, Вы писали:
I>Здравствуйте, jazzer, Вы писали:
J>>У тебя какая версия буста, кстати? J>>Попробуй последнюю, если сработает, значит, был баг и его пофиксили.
I>1.34.1, то есть почти самая последняя. Зато VC++ 6.0.
I>Если это баг в Boost.Regex, то это странно. На ровном месте ведь. Я в регулярных выражениях новичок и надеялся, что я сам что-нибудь неправильно сделал. Например, что нужно не (a)*b , а ^(a)*b$ или (a)*?b .
ну, скобки с захватом точно использовать не нужно, если тебе не нужен захват. Если нужны скобки для группировки, используй незахватывающие "(?".
Потом, если ты можешь привязать свой регексп к началу или концу строки, то лучше это делать хотя бы из соображений скорости.
Хотя, может, regex_match эту привязку делает автоматически, но все равно, лучше убедиться экспериментально.