用另一个字符串替换字符串的一部分 在C++中,用另一个字符串替换字符串的一部分是可能的吗?
基本上,我想这样做:用另一个字符串替换字符串的一部分 在C++中,用另一个字符串替换字符串的一部分是可能的吗?,c++,string,replace,substring,std,C++,String,Replace,Substring,Std,基本上,我想这样做: QString string("hello $name"); string.replace("$name", "Somename"); >但我想使用标准C++库。 STD::String 有一个方法,那就是你要找的吗?< /P> 你可以试试: s.replace(s.find("$name"), sizeof("$name") - 1, "Somename"); 我自己没有试过,只是阅读了find()和replace()的文档,是的,您可以这样做,但是您必须用字符串
QString string("hello $name");
string.replace("$name", "Somename");
<> >但我想使用标准C++库。 <代码> STD::String 有一个方法,那就是你要找的吗?< /P> 你可以试试:
s.replace(s.find("$name"), sizeof("$name") - 1, "Somename");
我自己没有试过,只是阅读了
find()
和replace()
的文档,是的,您可以这样做,但是您必须用字符串的find()成员找到第一个字符串的位置,然后用它的replace()成员替换
如果您打算使用标准库,您应该真正拥有一本涵盖所有这些内容的书。有一个函数可以在字符串()中查找子字符串,还有一个函数可以用另一个字符串()替换字符串中的特定范围,因此您可以将它们组合起来以获得想要的效果:
bool replace(std::string& str, const std::string& from, const std::string& to) {
size_t start_pos = str.find(from);
if(start_pos == std::string::npos)
return false;
str.replace(start_pos, from.length(), to);
return true;
}
std::string string("hello $name");
replace(string, "$name", "Somename");
作为对一条评论的回应,我认为
replaceAll
可能看起来像这样:
void replaceAll(std::string& str, const std::string& from, const std::string& to) {
if(from.empty())
return;
size_t start_pos = 0;
while((start_pos = str.find(from, start_pos)) != std::string::npos) {
str.replace(start_pos, from.length(), to);
start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx'
}
}
std::string dirSuite = replaceAll(replaceAll(relPath.parent_path().u8string(), "\\", "/"), ":", "");
要返回新字符串,请使用以下命令:
std::string ReplaceString(std::string subject, const std::string& search,
const std::string& replace) {
size_t pos = 0;
while ((pos = subject.find(search, pos)) != std::string::npos) {
subject.replace(pos, search.length(), replace);
pos += replace.length();
}
return subject;
}
如果需要性能,这里有一个修改输入字符串的优化函数,它不会创建字符串的副本:
void ReplaceStringInPlace(std::string& subject, const std::string& search,
const std::string& replace) {
size_t pos = 0;
while ((pos = subject.find(search, pos)) != std::string::npos) {
subject.replace(pos, search.length(), replace);
pos += replace.length();
}
}
测试:
std::string input = "abc abc def";
std::cout << "Input string: " << input << std::endl;
std::cout << "ReplaceString() return value: "
<< ReplaceString(input, "bc", "!!") << std::endl;
std::cout << "ReplaceString() input string not modified: "
<< input << std::endl;
ReplaceStringInPlace(input, "bc", "??");
std::cout << "ReplaceStringInPlace() input string modified: "
<< input << std::endl;
我通常使用:
std::string& replace(std::string& s, const std::string& from, const std::string& to)
{
if(!from.empty())
for(size_t pos = 0; (pos = s.find(from, pos)) != std::string::npos; pos += to.size())
s.replace(pos, from.size(), to);
return s;
}
它反复调用
std::string::find()
,以查找搜索字符串的其他匹配项,直到std::string::find()
没有找到任何内容为止。因为std::string::find()
返回匹配的位置,所以我们没有使迭代器无效的问题。对于C++11,您可以像这样使用std::regex
:
#include <regex>
...
std::string string("hello $name");
string = std::regex_replace(string, std::regex("\\$name"), "Somename");
#包括
...
std::string字符串(“hello$name”);
string=std::regex\u replace(string,std::regex(“\\$name”),“Somename”);
转义转义字符需要双反斜杠。这听起来像是一个选项
string.replace(string.find(“%s”)、string(“%s”).size()、“Something”)代码>
您可以将其封装在函数中,但这一行解决方案听起来可以接受。
问题是,这只会改变第一次出现,你可能想循环它,但是它也允许你用相同的符号(这个字符串中插入几个变量):(代码>%s) 我现在正在学习C++,但是编辑以前发布的一些代码,我可能会使用这样的东西。这使您可以灵活地替换1个或多个实例,还可以指定起点
using namespace std;
// returns number of replacements made in string
long strReplace(string& str, const string& from, const string& to, size_t start = 0, long count = -1) {
if (from.empty()) return 0;
size_t startpos = str.find(from, start);
long replaceCount = 0;
while (startpos != string::npos){
str.replace(startpos, from.length(), to);
startpos += to.length();
replaceCount++;
if (count > 0 && replaceCount >= count) break;
startpos = str.find(from, startpos);
}
return replaceCount;
}
如果所有字符串都是STD::String,如果使用<代码> siZOFF()/CUT>,字符的截断会出现奇怪的问题,因为它是针对C字符串而不是C++字符串的。修复方法是使用
std::string
的.size()
类方法
sHaystack.replace(sHaystack.find(sNeedle), sNeedle.size(), sReplace);
这将替换sHaystack内联——无需再对其执行=赋值
用法示例:
std::string sHaystack = "This is %XXX% test.";
std::string sNeedle = "%XXX%";
std::string sReplace = "my special";
sHaystack.replace(sHaystack.find(sNeedle),sNeedle.size(),sReplace);
std::cout << sHaystack << std::endl;
std::string sHaystack=“这是%XXX%测试。”;
std::string sNeedle=“%XXX%”;
std::string sReplace=“我的特别”;
替换(sHaystack.find(sNeedle),sNeedle.size(),sReplace);
std::cout如果您想快速完成,可以使用两次扫描方法。
伪代码:
首先解析。找到匹配的字符数李>
展开字符串的长度李>
第二个解析。当我们得到替换的匹配项时,从字符串的末尾开始,否则我们只复制第一个字符串中的字符
我不确定这是否可以优化到一个就地算法
和一个C++11代码示例,但我只搜索一个字符
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
void ReplaceString(string& subject, char search, const string& replace)
{
size_t initSize = subject.size();
int count = 0;
for (auto c : subject) {
if (c == search) ++count;
}
size_t idx = subject.size()-1 + count * replace.size()-1;
subject.resize(idx + 1, '\0');
string reverseReplace{ replace };
reverse(reverseReplace.begin(), reverseReplace.end());
char *end_ptr = &subject[initSize - 1];
while (end_ptr >= &subject[0])
{
if (*end_ptr == search) {
for (auto c : reverseReplace) {
subject[idx - 1] = c;
--idx;
}
}
else {
subject[idx - 1] = *end_ptr;
--idx;
}
--end_ptr;
}
}
int main()
{
string s{ "Mr John Smith" };
ReplaceString(s, ' ', "%20");
cout << s << "\n";
}
#包括
#包括
#包括
使用名称空间std;
void ReplaceString(字符串和主题、字符搜索、常量字符串和替换)
{
size_t initSize=subject.size();
整数计数=0;
对于(自动c:主题){
如果(c==搜索)+计数;
}
size\u t idx=subject.size()-1+count*replace.size()-1;
subject.resize(idx+1,“\0”);
字符串反向替换{replace};
反向(reverseReplace.begin(),reverseReplace.end());
char*end_ptr=&subject[initSize-1];
while(end_ptr>=&主题[0])
{
如果(*end_ptr==搜索){
用于(自动c:反向替换){
受试者[idx-1]=c;
--idx;
}
}
否则{
受试者[idx-1]=*结束ptr;
--idx;
}
--结束ptr;
}
}
int main()
{
字符串s{“John Smith先生”};
替换字符串,,“%20”);
cout我自己的实现,考虑到字符串只需要调整一次大小,然后就可以进行替换
template <typename T>
std::basic_string<T> replaceAll(const std::basic_string<T>& s, const T* from, const T* to)
{
auto length = std::char_traits<T>::length;
size_t toLen = length(to), fromLen = length(from), delta = toLen - fromLen;
bool pass = false;
std::string ns = s;
size_t newLen = ns.length();
for (bool estimate : { true, false })
{
size_t pos = 0;
for (; (pos = ns.find(from, pos)) != std::string::npos; pos++)
{
if (estimate)
{
newLen += delta;
pos += fromLen;
}
else
{
ns.replace(pos, fromLen, to);
pos += delta;
}
}
if (estimate)
ns.resize(newLen);
}
return ns;
}
这可能是更好的使用
void replace(string& input, const string& from, const string& to)
{
while(true)
{
size_t startPosition = input.find(from);
if(startPosition == string::npos)
break;
input.replace(startPosition, from.length(), to);
}
}
您可以使用此代码删除子字符串,也可以替换,还可以删除额外的空白。
代码:
#包括
使用名称空间std;
void removespace(字符串和字符串)
{
int n=str.length();
int i=0,j=-1;
bool spaceFound=false;
而(++js;
对于(int i=s.find(“WUB”);i>=0;i=s.find(“WUB”))
{
s、 替换(i,3,“”);
}
移除空间;
从我看到的情况来看,std::string replace方法没有像我希望的那样接受两个字符串。这对我不起作用。sizeof应该被string(“Somename”).size()替换-1@TimZaman:这让我很困惑,文档清楚地说明可以从C样式字符串初始化。第二个参数的长度应为“$name”(而不是“Somename”的长度),不是吗?如果有多个“$name”出现,这将不起作用<代码> >代码> S>。代码可能是AcOs,抱歉,是C,不是C++;我希望我可以投票。@ Pyl I认为这也必须被问到C++,但是我不能发现它有STD标签,但是也许你可能对Boost的字符串算法感兴趣,它也包含了广泛的替换算法的选择。(in place/copy,区分大小写/不区分大小写,替换第一个/最后一个/所有/n-th)。@Michael Mrozek在上有一个,但它更新了,并且这里的替换所有方法更健壮。可能是duplica
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
void ReplaceString(string& subject, char search, const string& replace)
{
size_t initSize = subject.size();
int count = 0;
for (auto c : subject) {
if (c == search) ++count;
}
size_t idx = subject.size()-1 + count * replace.size()-1;
subject.resize(idx + 1, '\0');
string reverseReplace{ replace };
reverse(reverseReplace.begin(), reverseReplace.end());
char *end_ptr = &subject[initSize - 1];
while (end_ptr >= &subject[0])
{
if (*end_ptr == search) {
for (auto c : reverseReplace) {
subject[idx - 1] = c;
--idx;
}
}
else {
subject[idx - 1] = *end_ptr;
--idx;
}
--end_ptr;
}
}
int main()
{
string s{ "Mr John Smith" };
ReplaceString(s, ' ', "%20");
cout << s << "\n";
}
template <typename T>
std::basic_string<T> replaceAll(const std::basic_string<T>& s, const T* from, const T* to)
{
auto length = std::char_traits<T>::length;
size_t toLen = length(to), fromLen = length(from), delta = toLen - fromLen;
bool pass = false;
std::string ns = s;
size_t newLen = ns.length();
for (bool estimate : { true, false })
{
size_t pos = 0;
for (; (pos = ns.find(from, pos)) != std::string::npos; pos++)
{
if (estimate)
{
newLen += delta;
pos += fromLen;
}
else
{
ns.replace(pos, fromLen, to);
pos += delta;
}
}
if (estimate)
ns.resize(newLen);
}
return ns;
}
std::string dirSuite = replaceAll(replaceAll(relPath.parent_path().u8string(), "\\", "/"), ":", "");
void replace(string& input, const string& from, const string& to)
{
while(true)
{
size_t startPosition = input.find(from);
if(startPosition == string::npos)
break;
input.replace(startPosition, from.length(), to);
}
}
#include<bits/stdc++.h>
using namespace std ;
void removeSpaces(string &str)
{
int n = str.length();
int i = 0, j = -1;
bool spaceFound = false;
while (++j <= n && str[j] == ' ');
while (j <= n)
{
if (str[j] != ' ')
{
if ((str[j] == '.' || str[j] == ',' ||
str[j] == '?') && i - 1 >= 0 &&
str[i - 1] == ' ')
str[i - 1] = str[j++];
else
str[i++] = str[j++];
spaceFound = false;
}
else if (str[j++] == ' ')
{
if (!spaceFound)
{
str[i++] = ' ';
spaceFound = true;
}
}
}
if (i <= 1)
str.erase(str.begin() + i, str.end());
else
str.erase(str.begin() + i - 1, str.end());
}
int main()
{
string s;
cin>>s;
for(int i=s.find("WUB");i>=0;i=s.find("WUB"))
{
s.replace(i,3," ");
}
removeSpaces(s);
cout<<s<<endl;
return 0;
}