在c++中实现一个查找和替换过程
Implementing a find-and-replace procedure in C++
只是为了好玩,我正在尝试编写一个像文字处理器那样的查找和替换过程。我想知道是否有人可以帮助我找出我做错了什么(我得到一个Timeout
错误),并可以帮助我写一个更优雅的过程。
#include <iostream>
#include <string>
void find_and_replace(std::string& text, const std::string& fword, const std::string& rword)
{
for (std::string::iterator it(text.begin()), offend(text.end()); it != offend;)
{
if (*it != ' ')
{
std::string::iterator wordstart(it);
std::string thisword;
while (*(it+1) != ' ' && (it+1) != offend)
thisword.push_back(*++it);
if (thisword == fword)
text.replace(wordstart, it, rword);
}
else {
++it;
}
}
}
int main()
{
std::string S("Yo, dawg, I heard you like ...");
std::string f("dawg");
std::string w("dog");
// Replace every instance of the word "dawg" with "dog":
find_and_replace(S, f, w);
std::cout << S;
return 0;
}
像大多数编辑器一样,查找和替换将涉及常规的表达式。如果你想要的只是字面意思替换,你需要的函数是std::search
,来找到文本要替换,而std::string::replace
,要做实际的替换。你将面临的唯一问题是:std::string::replace
可以使你的迭代器失效。你可以总是从字符串的开头开始搜索,但是这个可能导致无休止的循环,如果替换文本包含搜索字符串(如s/vector/std::vector/
)。您应该转换从std::search
返回的迭代器在执行替换(offset
= iter - str.begin()
)之前,将其偏移量转换为字符串,然后将其转换回迭代器( iter = str.begin() + offset + replacement.size()
)。(添加replacement.size()
是为了避免重新扫描文本你刚刚插入,这可能会导致无限循环,对于
- 使用
text.replace
可能会使任何进入文本的迭代器失效(即it
和offend
):这是不安全的 - 将每个字符复制到一个临时字符串(每次开始一个新单词时创建和销毁)是浪费的
最简单的方法是:
- 使用
find
找到第一个匹配的子字符串:它返回一个position
,当你替换子字符串时不会无效 - 检查是否:
- 子字符串位于文本的开头,或者前面有分隔符
- 子字符串位于文本的末尾,或者后面有一个分隔符
- 如果2.1和2.2为真,替换子字符串
- 如果你替换了它,增加
position
(从1)由你的替换字符串的长度 - 否则将
position
增加您搜索的字符串的长度 - 从1开始重复,这次从
position
(从4/5)开始查找
std::string::npos
时结束
1)你不把找到的单词的第一个符号推入"thisword"变量
2)您只使用空格符号' '作为分隔符,那么逗号','呢?你的程序会找到单词"dawg ",而不是"dawd"
下面的代码可以工作,但是您应该考虑其他单词分隔符。你真的只需要替换整个单词,还是仅仅替换符号序列?
#include <iostream>
#include <string>
void find_and_replace(std::string& text, const std::string& fword, const std::string& rword)
{
for (std::string::iterator it(text.begin()), offend(text.end()); it != offend;)
{
if (*it != ' ' && *it != ',')
{
std::string::iterator wordstart(it);
std::string thisword;
while ((it) != offend && *(it) != ' ' && *(it) != ',')
thisword.push_back(*it++);
if (thisword == fword)
text.replace(wordstart, it, rword);
}
else {
++it;
}
}
}
int main()
{
std::string S("Yo, dawg, I heard you like ...");
std::string f("dawg");
std::string w("dog");
// Replace every instance of the word "dawg" with "dog":
find_and_replace(S, f, w);
std::cout << S;
return 0;
}
相关文章:
- 我试图编写一个代码来查找一个单词是否是回文,但它不起作用。怎么了?
- 我如何在一串随机生成的字母I C 中查找一个单词
- 查找一个阵列包含在另一个C++中的次数
- 在数组中查找一个或多个模式
- 在树中查找一个路径/子路径,使权重之和小于给定的整数
- 如何查找一个物体是在一个航路点之前还是之后
- 查找一个区域中未包含在另一个区域中的第一个元素
- 使用string.at()在字符串c++中查找一个空格
- 在数组中查找一个变量,哪个和最接近目标和
- 查找一个数字是否是其他一些数字的公共倍数
- 查找一个字符串(如果它存在于另一个字符串中)
- 在旋转矩形内查找一个点
- 在双映射容器中查找一个整数
- 在c中的另一个字符数组中查找一个字符数组
- 存储一组不重叠的范围,并严格查找一个值是否存在于任何一个范围中
- 从文本文件中查找一个单词,然后使用c++显示该单词所在的行号
- 在二维数组中查找一个值的多个索引
- 在shared_ptr的unordered_set中查找一个值
- 在文本文件中查找一个数字并输出该数据行
- 如何通过检查v. dictionary来查找一个短语中删除空格的单词数