2015-02-14 1 views
5

У меня есть огромный абзац текста, хранящийся в std :: string с именем «text». В этой строке я заменяю определенные шаблоны пробелом, используя библиотеку regex boost. Вот мой код.Замена регулярного выражения на месте с помощью Boost

// Remove times of the form (00:33) and (1:33) 
boost::regex rgx("\\([0-9.:]*\\)"); 
text = boost::regex_replace(text, rgx, " "); 

// Remove single word HTML tags 
rgx.set_expression("<[a-zA-Z/]*>"); 
text = boost::regex_replace(text, rgx, " "); 

// Remove comments like [pause], [laugh] 
rgx.set_expression("\\[[a-zA-Z]* *[a-zA-Z]*\\]"); 
text = boost::regex_replace(text, rgx, " "); 

// Remove comments of the form <...> 
rgx.set_expression("<.+?>"); 
text = boost::regex_replace(text, rgx, " "); 

// Remove comments of the form {...} 
rgx.set_expression("\\{.+?\\}"); 
text = boost::regex_replace(text, rgx, " "); 

// Remove comments of the form [...] 
rgx.set_expression("\\[.+?\\]"); 
text = boost::regex_replace(text, rgx, " "); 

Из моего понимания, каждый раз, когда я запускаю функцию regex_replace, он создает новую строку и записывает вывод на него. Если я запустил функцию regex_replace с N различными шаблонами, он выделит N новых строк (удалив старые).

Поскольку распределение памяти занимает много времени, существует ли способ выполнить замену «на месте», не выделяя новую строку?

ответ

2

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

boost::regex_replace(text.begin(), text.begin(), text.end(), rgx, 
        " "); 
+0

Спасибо, я думаю, что это сделает. –

+2

Предупреждение: результат, скорее всего, не определен, если форматирование заменяет соответствие другой строкой длины. (!!!) (В документации ничего не говорится о диапазонах ввода/вывода с псевдонимом/перекрытием) – sehe

0

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

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

boost::regex rgx("(\\([0-9.:]*\\))|" 
       "(<[a-zA-Z/]*>)|" 
       "(\\[[a-zA-Z]* *[a-zA-Z]*\\])|" 
       "(<.+?>)|" 
       "(\\{.+?\\})|" 
       "(\\[.+?\\])"); 
text = boost::regex_replace(text, rgx, " "); 
Смежные вопросы