Обрабатываем знаки препинания
После того как мы разбили каждую строку на слова, необходимо избавиться от знаков препинания. Пока из строки
magical but untamed. "Daddy, shush, there is no such thing,"
у нас получился такой набор слов:
magical
but
untamed.
"Daddy,
shush,
there
is
no
such
thing,"
Как нам теперь удалить ненужные знаки препинания? Для начала определим строку, содержащую все символы, которые мы хотим удалить:
string filt_elems( "\",.;:!?)(\\/" );
(Обратная косая черта указывает на то, что следующий за ней символ должен в данном контексте восприниматься буквально, а не как специальная величина. Так, \"
обозначает символ двойной кавычки, а не конец строки, а \\ – символ обратной косой черты.)
Теперь можно применить функцию-член find_first_of() для поиска всех вхождений нежелательных символов:
while (( pos = word.find_first_of( filt_elems, pos )) |
!= string::npos )
Найденный символ удаляется с помощью функции-члена erase():
word.erase(pos,1);
Первый аргумент этой функции означает позицию подстроки, а второй – ее длину. Мы удаляем один символ, находящийся в позиции pos. Второй аргумент является необязательным; если его опустить, будут удалены все символы от pos до конца строки.
Вот полный текст функции filter_text(). Она имеет два параметра: указатель на вектор строк, содержащий текст, и строку с символами, которые нужно убрать.
void filter_text( vector<string> *words, string filter ) { vector<string>::iterator iter = words->begin(); vector<string>::iterator iter_end = words->end(); // Если filter не задан, зададим его сами if ( ! filter.size() ) filter.insert( 0, "\".," ); while ( iter != iter_end ) { string::size_type pos = 0; // удалим каждый найденный элемент while (( pos = (*iter).find_first_of( filter, pos )) != string::npos ) (*iter).erase(pos,1); iter++; } |
}
Почему мы не увеличиваем значение pos на каждой итерации? Что было бы, если бы мы написали:
while (( pos = (*iter).find_first_of( filter, pos )) != string::npos ) { (*iter).erase(pos,1); ++ pos; // неправильно... |
Возьмем строку
thing,"
На первой итерации pos
получит значение 5 , т.е. позиции, в которой находится запятая. После удаления запятой строка примет вид
thing"
Теперь в 5-й позиции стоит двойная кавычка. Если мы увеличим значение pos, то пропустим этот символ.
Так мы будем вызывать функцию filter_text():
string filt_elems( "\",.;:!?)(\\/" ); |
А вот часть распечатки, сделанной тестовой версией filter_text():
filter_text: untamed.
found! : pos: 7.
after: untamed
filter_text: "Daddy,
found! : pos: 0.
after: Daddy,
found! : pos: 5.
after: Daddy
filter_text: thing,"
found! : pos: 5.
after: thing"
found! : pos: 5.
after: thing
filter_text: "I
found! : pos: 0.
after: I
filter_text: Daddy,
found! : pos: 5.
after: Daddy
filter_text: there?"
found! : pos: 5.
after: there"
found! : pos: 5.
after: there
Упражнение 6.15
Напишите программу, которая удаляет все символы, кроме STL из строки:
"/.+(STL).$1/"
используя сначала erase(pos,count), а затем erase(iter,iter).
Упражнение 6.16
Напишите программу, которая с помощью разных функций вставки из строк
string sentence( "kind of" ); string s1 ( "whistle" ) |
составит предложение
"A whistling-dixie kind of walk"