Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
DarkMasterW
4 / 4 / 0
Регистрация: 25.10.2013
Сообщений: 230
#1

Regex_replace краши - C++

15.07.2014, 02:04. Просмотров 994. Ответов 11
Метки нет (Все метки)

собственно есть набор строк поиска/замены. Не могу понять почему спотыкается на:
искомая строка: ^(\[TEMPLATE.*\])(\n)((.|\n)*?)(item=)(i_gold,)
замена: %%%%% %%%%%

Правила существенно обрезаны. Строка замены на краш не влияет. А вот с искомой какие-то чудеса творятся.
если меняем строку
^(\[TEMPLATE.*\])(\n)((.|\n)*?)(item=)(i_gold) - крашит.
^(\[TEMPLATE.*\])(\n)((.|\n)*?)(item=)(i_) - шуршит.

Если текст в котором ищем обрезать в до 500 строк - все шуршит в обоих случаях, заменяет.
C++
1
2
3
4
std::vector<std::vector<string> > matchAndRules;
....
std::regex rgExRule(matchAndRules[v][0], std::tr1::regex_constants::icase);
inputTextStr = std::regex_replace(inputTextStr, rgExRule, matchAndRules[v][1]);
Добавлено через 9 минут
При краше отладчик говорит(моя такое не понимать):
Необработанное исключение по адресу 0x0FCA3977 (msvcr120d.dll) в RegExpTXT.exe: 0xC00000FD: Stack overflow (параметры: 0x00000000, 0x001F2000).
ссылается на 262 строку dbgrpt.c
return _VCrtDbgReportT(nRptType,returnAddress,szFile,nLine,szModule,szFormat,arglist);

Спасибо.
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
15.07.2014, 02:04
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Regex_replace краши (C++):

Regex_replace с callback - C++
Возможно я плохо искал, но что-то я никак не могу понять, как в C++ правильно выполнять такую операцию: string s =...

Почему не работает функция std::regex_replace(temp,"amp;",""); - C++
Пробую вызывать функцию std::regex_replace(temp,&quot;amp;&quot;,&quot;&quot;); Пишет ошибку: test_ok_ruDlg.cpp 1&gt;d:\visual studio...

regex_replace - Boost C++
Есть ли способ сделать замену в зависимости от найденного подвыражения, то есть, если найдено второе подвыражение, то заменить на второй...

Как предотвращать краши из-за HttpWebRequest-запросов - Visual Basic .NET
Здравствуйте. Столкнулся с проблемой. Иногда использую при запросах прокси и очень уж часто программу полностью крашит. Иногда с первого...

Медленные сектора и краши программ на почти новом HDD - Жесткие диски
Есть почти новый (около года) HGST HTS721010A9E630, гигабайтный ноутбучный диск. Всё было ничего, но недавно начало странное, программы...

При загрузке оперативной памяти на 75 - 80% начинаются подвисания, краши - Материнские платы
Есть материнская плата 760gma-p34 (fx) Проблема: Обнаружил проблему: при загрузке оперативной памяти на 75 - 80% начинаются &quot;ништячки&quot;...

Regex_replace с callback - C++
Возможно я плохо искал, но что-то я никак не могу понять, как в C++ правильно выполнять такую операцию: string s =...

Почему не работает функция std::regex_replace(temp,"amp;",""); - C++
Пробую вызывать функцию std::regex_replace(temp,&quot;amp;&quot;,&quot;&quot;); Пишет ошибку: test_ok_ruDlg.cpp 1&gt;d:\visual studio...

regex_replace - Boost C++
Есть ли способ сделать замену в зависимости от найденного подвыражения, то есть, если найдено второе подвыражение, то заменить на второй...

Как предотвращать краши из-за HttpWebRequest-запросов - Visual Basic .NET
Здравствуйте. Столкнулся с проблемой. Иногда использую при запросах прокси и очень уж часто программу полностью крашит. Иногда с первого...

Медленные сектора и краши программ на почти новом HDD - Жесткие диски
Есть почти новый (около года) HGST HTS721010A9E630, гигабайтный ноутбучный диск. Всё было ничего, но недавно начало странное, программы...

При загрузке оперативной памяти на 75 - 80% начинаются подвисания, краши - Материнские платы
Есть материнская плата 760gma-p34 (fx) Проблема: Обнаружил проблему: при загрузке оперативной памяти на 75 - 80% начинаются &quot;ништячки&quot;...

Regex_replace с callback - C++
Возможно я плохо искал, но что-то я никак не могу понять, как в C++ правильно выполнять такую операцию: string s =...

Почему не работает функция std::regex_replace(temp,"amp;",""); - C++
Пробую вызывать функцию std::regex_replace(temp,&quot;amp;&quo

Regex_replace с callback - C++
Возможно я плохо искал, но что-то я никак не могу понять, как в C++ правильно выполнять такую операцию: string s =...

Почему не работает функция std::regex_replace(temp,"amp;",""); - C++
Пробую вызывать функцию std::regex_replace(temp,&quot;amp;&quot;,&quot;&quot;); Пишет ошибку: test_ok_ruDlg.cpp 1&gt;d:\visual studio...

regex_replace - Boost C++
Есть ли способ сделать замену в зависимости от найденного подвыражения, то есть, если найдено второе подвыражение, то заменить на второй...

Как предотвращать краши из-за HttpWebRequest-запросов - Visual Basic .NET
Здравствуйте. Столкнулся с проблемой. Иногда использую при запросах прокси и очень уж часто программу полностью крашит. Иногда с первого...

Медленные сектора и краши программ на почти новом HDD - Жесткие диски, HDD
Есть почти новый (около года) HGST HTS721010A9E630, гигабайтный ноутбучный диск. Всё было ничего, но недавно начало странное, программы...

При загрузке оперативной памяти на 75 - 80% начинаются подвисания, краши - Материнские платы
Есть материнская плата 760gma-p34 (fx) Проблема: Обнаружил проблему: при загрузке оперативной памяти на 75 - 80% начинаются &quot;ништячки&quot;...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Renji
1968 / 1366 / 308
Регистрация: 05.06.2014
Сообщений: 3,898
15.07.2014, 17:15 #2
При краше отладчик говорит(моя такое не понимать):
Говорит что стек переполнился. Иными словами, кто-то, где-то вошел в бесконечную рекурсию. Пересобрать в дебаг-сборке, запустить еще раз из отладчика и посмотреть на каком именно месте программа упадет.
0
DarkMasterW
4 / 4 / 0
Регистрация: 25.10.2013
Сообщений: 230
15.07.2014, 20:56  [ТС] #3
xthrow.cpp 53 строка(тут третья).
C++
1
2
3
4
5
CRTIMP2_PURE _NO_RETURN(__CLRCALL_PURE_OR_CDECL _Xregex_error(regex_constants::error_type _Code))
    {   // report a regex_error
    _THROW_NCEE(regex_error, _Code);
    }
_STD_END
И что мне это дало? Пока совсем не представляю куда копать.

Можно как-то вытащить строку с которой происходило сравнение и шаг в правиле поиска?

Добавлено через 12 минут
xthrow.cpp 54 строка(тут четвертая). Ошибся...
0
Renji
1968 / 1366 / 308
Регистрация: 05.06.2014
Сообщений: 3,898
15.07.2014, 22:03 #4
И что мне это дало? Пока совсем не представляю куда копать.
Отладчик должен где-то рядышком показывать стек вызовов. Найди там собственноручно написанную процедуру и дважды кликни по ней. Куда после этого перебрасывает?
0
DarkMasterW
4 / 4 / 0
Регистрация: 25.10.2013
Сообщений: 230
16.07.2014, 07:20  [ТС] #5
кидает сюда:
C++
1
        inputTextStr = std::regex_replace(inputTextStr, rgExRule, matchAndRules[v][1]);
Собственно я и так знал, что крашит этот самый реплейс(см название темы). Почему крашит то? Что ему не так?
0
castaway
Эксперт С++
4915 / 3023 / 370
Регистрация: 10.11.2010
Сообщений: 11,080
Записей в блоге: 10
Завершенные тесты: 1
16.07.2014, 07:55 #6
Какой компилятор то?
0
Renji
1968 / 1366 / 308
Регистрация: 05.06.2014
Сообщений: 3,898
16.07.2014, 08:15 #7
Собственно я и так знал, что крашит этот самый реплейс(см название темы). Почему крашит то? Что ему не так?
1) Посмотреть сколько всего строк болтается в стеке вызовов. Если буквально 100500, значит искать кривую рекурсию.
2) Посмотреть в отладчике размер matchAndRules (должен быть больше v), размер matchAndRules[v] (должен быть больше единицы) и содержимое matchAndRules[v][1].
3) Обрезать код до загрузки inputTextStr и выполнения inputTextStr = std::regex_replace(inputTextStr, rgExRule, matchAndRules.at(v).at(1)); Все остальное выкинуть.
Если после всего этого программа продолжает падать, остается лишь считать что кривая библиотека регэекспов.
0
DarkMasterW
4 / 4 / 0
Регистрация: 25.10.2013
Сообщений: 230
17.07.2014, 12:43  [ТС] #8
Цитата Сообщение от castaway Посмотреть сообщение
Какой компилятор то?
MSVS 2013
Цитата Сообщение от Renji Посмотреть сообщение
1) Посмотреть сколько всего строк болтается в стеке вызовов. Если буквально 100500, значит искать кривую рекурсию.
Где посмотреть?
Цитата Сообщение от Renji Посмотреть сообщение
3) Обрезать код до загрузки inputTextStr и выполнения inputTextStr = std::regex_replace(inputTextStr, rgExRule, matchAndRules.at(v).at(1)); Все остальное выкинуть.
Если после всего этого программа продолжает падать, остается лишь считать что кривая библиотека регэекспов.
Обрезал до:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
#include <ctime>
 
#include <regex>
#include <string>
 
#include <fstream>
#include <iomanip>
 
#include <vector>
 
using namespace std;
 
int main()
{
    setlocale(LC_ALL, "RUS");
 
 
    string inputTextStr; // строка
 
    ifstream inputTextFile; inputTextFile.open("I:\\Downloads\\RegExp\\inputText.txt", ios::binary);
    if (inputTextFile.good())
    {
        inputTextFile.seekg(0, ios::end);
        inputTextStr.resize(inputTextFile.tellg());
        inputTextFile.seekg(0, ios::beg);
 
        inputTextFile.read((char*)inputTextStr.data(), inputTextStr.size());
        inputTextFile.close();
    }
 
    cout << "1:\n";
    string str1 = "\\]((.|\\n)*?)(ITEM=tm_)";
    string str2 = "%%%%% %%%%%";
    std::regex rgExRule(str1, std::tr1::regex_constants::icase);
    inputTextStr = std::regex_replace(inputTextStr, rgExRule, str2);
    cout << inputTextStr;
    cin.get();
}
Опытным путем установлено, что конструкция ((.|\\n)*?) приводит к крашам за исключением очень коротких файлов в пару десятков строк. Чем больший кусок текста охватывает правило, тем меньший должен быть по размеру файл. Что собственно очень хорошо вписывается в краши ((.|\\n)*?). Там размер какого-нибудь буфера не ограничен случаем?
Цитата Сообщение от DarkMasterW Посмотреть сообщение
^(\\[TEMPLATE.*\\])(\\n)((.|\\n)*?)(item=)(i_gold) - крашит.
^(\\[TEMPLATE.*\\])(\\n)((.|\\n)*?)(item=)(i_) - шуршит.
Этот кусок так же в целом вписывается. Строки (item=)(i_) встречаются через одну, (item=)(i_gold) может и раз через двадцать могут быть. Правда от \\[TEMPLATE.*\\] она всегда находится в 0-2 строках, что несколько озадачивает.
0
Renji
1968 / 1366 / 308
Регистрация: 05.06.2014
Сообщений: 3,898
17.07.2014, 13:43 #9
Где посмотреть?
Там где ты стек вызовов нашел. Он должен прокручиваться также как любой другой список. Если, конечно, там есть что прокручивать.
Обрезал до:
Тогда последний тест - поставить boost и использовать его вместо std::regex (синтаксис практически тот же, только с заменой std:: на boost:: ). Если после этого программа внезапно перестанет падать, значит глюк точно в реализации std. C++11 вроде как еще в стадии финальных доработок напильником, так что в реализации действительно может быть косяк.
1
DarkMasterW
4 / 4 / 0
Регистрация: 25.10.2013
Сообщений: 230
17.07.2014, 20:11  [ТС] #10
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <iostream>
#include <ctime>
 
#include <regex>
#include <string>
 
#include <fstream>
#include <iomanip>
 
#include <vector>
 
#include <boost/regex.hpp>
 
using namespace std;
 
int main()
{
    setlocale(LC_ALL, "RUS");
 
 
    string inputTextStr; // строка
 
    ifstream inputTextFile; inputTextFile.open("I:\\Downloads\\RegExp\\inputText.txt", ios::binary);
    if (inputTextFile.good())
    {
        inputTextFile.seekg(0, ios::end);
        inputTextStr.resize(inputTextFile.tellg());
        inputTextFile.seekg(0, ios::beg);
 
        inputTextFile.read((char*)inputTextStr.data(), inputTextStr.size());
        inputTextFile.close();
    }
 
    cout << "1:\n";
    string str1 = "\n(\\[TEMPLATE.*\\].*)(\\n)((.|\\n)*?)(item=)(i_gold,)";
    string str2 = "%%%%% %%%%%";
    boost::regex rgExRule(str1, std::tr1::regex_constants::icase);
    inputTextStr = boost::regex_replace(inputTextStr, rgExRule, str2);
    cout << inputTextStr;
    cin.get();
}
1>------ Сборка начата: проект: Tmp, Конфигурация: Debug Win32 ------
1>LINK : fatal error LNK1104: не удается открыть файл "libboost_regex-vc120-mt-gd-1_55.lib"

Regex_replace краши

include не подчеркивает, позволяет открыть boost/regex.hpp через ПКМ. Видимо все-таки видит...

Добавлено через 1 час 15 минут
Не ту папку с либами буста указал. Надо было lib64-msvc-12.0.

Буст тоже крашит... Вот стек вызовов. Что с ним не так не понимаю. Регексп вроде нормальный... По крайней мере в RegEx Coach на ура съедается...

Regex_replace краши

Через STD словил новую радость:
Unhandled exception at 0x000007FEFDC3940D in Tmp.exe: Microsoft C++ exception: std::regex_error at memory location 0x00000000000DBB40.
if (0 < _Max_complexity_count && --_Max_complexity_count <= 0)
_Xregex_error(regex_constants::error_complexity);
внутри regex
0
DiffEreD
1431 / 768 / 95
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
17.07.2014, 23:00 #11
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
В boost еще есть replace_regex и replace_all_regex. Ваша регулярка у меня работает, никаких проблем не вижу. Компилятор g++ 4.8
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
#include <string>
#include <boost/algorithm/string/regex.hpp>
 
int main()
{
   std::string Input1 =
         "[teMPLATExxxxfdsdg]\n"
         "\n"
         "first\n"
         "second\n"
         "third\n"
         "item=i_gold";
 
   std::string Input2 =
         "[teMPLATExxxxfdsdg]\n"
         "\n"
         "first\n"
         "second\n"
         "third\n"
         "itNOTem=i_gold";
 
   std::string replace = "%%%%% %%%%%";
   boost::regex reg(R"(\[TEMPLATE.*\](\n)((.|\n)*?)(item=i_gold))", boost::regex::icase);
   boost::replace_all_regex(Input1, reg, replace);
   boost::replace_all_regex(Input2, reg, replace);
 
   std::cout << Input1 << "\n\n";
   std::cout << Input2 << "\n\n";
 
   return 0;
}
0
DarkMasterW
4 / 4 / 0
Регистрация: 25.10.2013
Сообщений: 230
18.07.2014, 10:56  [ТС] #12
inputText очень маленький. Оно и у меня на таком крашить не будет. Хотя бы 1000 строк сделай.

boost::replace_all_regex - так же краш.
boost::replace_regex - выполнил. Я подозревал, что по 1 он выполнять будет... Что-то где-то забивается от объема. А можно вернуть указатель на начало/конец реплейса? Уже думаю велосипед изобретать с единичными вызовами...

C++
1
2
3
4
    for (int b = 0; b < 225; b++){
        boost::replace_regex(inputTextStr, rgExRule, str2);
        cout << b << "\n";
    }
строк для замены 223. Все исправно заменяет. На последней итерации, когда уже строк совпадающих нет вылетает краш... Но я то откуда знаю сколько строк будет на совпадения?

Добавлено через 9 минут
Отбой радости. Урезанный регексп был после экспериментов. Все так же крашит... Причем на 1 же проходе. В урезанном состоянии отрезал хвост файла:
Кликните здесь для просмотра всего текста
ITEM=random_art_high,R500




















[EoF]
и краша на последнем проходе не стало. Вот только то, что нужно так и не работает и не понятно почему...

Добавлено через 11 часов 19 минут
С бустом все завелось и нормально работает. Флаг изначально не поменял std'шный на boost::regex::icase.
Всем большое спасибо за помощь.
0
18.07.2014, 10:56
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru