Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/159.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/tensorflow/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何查找和替换字符串中出现的所有子字符串?_C++_String_Algorithm_Str Replace - Fatal编程技术网

C++ 如何查找和替换字符串中出现的所有子字符串?

C++ 如何查找和替换字符串中出现的所有子字符串?,c++,string,algorithm,str-replace,C++,String,Algorithm,Str Replace,我需要搜索字符串并编辑其格式 到目前为止,我可以替换第一次出现的字符串,但无法替换下一次出现的字符串 这就是我的工作,有点: if(chartDataString.find("*A") == string::npos){ return;} else{chartDataString.replace(chartDataString.find("*A"), 3,"[A]\n");} 如果找不到字符串,就不会打印任何内容,所以这不好 我知道我需要遍历整个字符串chartDataString并替换所有出

我需要搜索字符串并编辑其格式

到目前为止,我可以替换第一次出现的字符串,但无法替换下一次出现的字符串

这就是我的工作,有点:

if(chartDataString.find("*A") == string::npos){ return;}
else{chartDataString.replace(chartDataString.find("*A"), 3,"[A]\n");}
如果找不到字符串,就不会打印任何内容,所以这不好

我知道我需要遍历整个字符串chartDataString并替换所有出现的字符串。我知道有很多类似的帖子,但我不明白(像这样)

我也尝试过这样做来循环字符串:

string toSearch = chartDataString;
string toFind = "*A:";
for (int i = 0; i<toSearch.length() - toFind.length(); i++){
   if(toSearch.substr(i, toFind.length()) == toFind){
       chartDataString.replace(chartDataString.find(toFind), 3, "[A]\n");   
   }
}

find
函数采用可选的第二个参数:开始搜索的位置。默认情况下,这是零

开始搜索下一个匹配项的好位置是插入上一个替换项的位置,加上该替换项的长度。例如,如果我们在位置7插入一个长度为3的字符串,那么下一个
find
应该从位置10开始

如果搜索字符串恰好是替换的子字符串,这种方法将避免无限循环。想象一下,如果您尝试将所有出现的
日志
替换为
模拟
,但不要跳过替换。

在中进行替换相当尴尬(可能效率不太高) 地点。我通常使用以下函数:

std::string
replaceAll( std::string const& original, std::string const& from, std::string const& to )
{
    std::string results;
    std::string::const_iterator end = original.end();
    std::string::const_iterator current = original.begin();
    std::string::const_iterator next = std::search( current, end, from.begin(), from.end() );
    while ( next != end ) {
        results.append( current, next );
        results.append( to );
        current = next + from.size();
        next = std::search( current, end, from.begin(), from.end() );
    }
    results.append( current, next );
    return results;
}
基本上,只要可以找到
开始,将中间文本和
追加到
,并前进 从转到下一个
实例。在末尾,您可以附加任何文本
在
中的最后一个
实例之后

(如果你要在C++中做很多编程,那很可能是 习惯使用迭代器是个好主意,如上所述, 而不是

std::string
的特殊成员函数。 上面的事情可以与任何C++一起工作 由于这个原因,容器类型更为惯用。)

尝试以下方法

const std::string s = "*A";
const std::string t = "*A\n";

std::string::size_type n = 0;
while ( ( n = chartDataString.find( s, n ) ) != std::string::npos )
{
    chartDataString.replace( n, s.size(), t );
    n += t.size();
}

如果
boost
可用,您可以使用以下选项:

std::string origStr = "this string has *A and then another *A";
std::string subStringToRemove = "*A";
std::string subStringToReplace = "[A]";

boost::replace_all(origStr , subStringToRemove , subStringToReplace);
对原始字符串执行修改,或

std::string result = boost::replace_all_copy(origStr , subStringToRemove , subStringToReplace);

在不修改原始字符串的情况下执行修改。

如果需要反转的字符串大小不同:

void            Replace::replace(std::string & str, std::string const & s1, std::string const & s2)
{
    size_t      pos;

    pos = 0;
    while ((pos = str.find(s1, pos)) != std::string::npos)
    {
        str.erase(pos, s1.length());
        str.insert(pos, s2);
        pos += s2.length();
    }
    return ;
}

使用C++11提供的std::regex_替换。这正是你想要的,而且更多

字符串替换全部(字符串删除、字符串替换、字符串行){


}

如何使用
std::regex
boost::regex
?boost有一个
replace\u all
功能。如何找出第一次出现的位置?@Sarah您已经在示例代码中使用它来执行第一次替换!它是
find
的返回值。算法类似于1。将一个位置初始化为零;2.查找从位置开始的子字符串。3.如果未找到子字符串,则完成。否则:4。在位置处更换子串。5.将替换字符串的长度添加到该位置。6.回到第二步。我真的很想用这个,但我认为它不起作用,我也不确定如何使它起作用。当我调用replaceAll(chartDataString,“*A”,“[A]\n”);实际上什么都没发生,我也不知道该怎么做work@Sarah它对我有用。(事实上,它是从生产代码中采用的。)您确定
chartDataString
包含序列
“*A”
?你在看返回值吗;此函数不会将
原始
中的任何内容从
更改为
?(一般来说,使用纯函数比使用修改现有对象的函数要干净得多。性能有时会有所不同,但作为一般规则,更喜欢纯函数而不是变异函数。)但如果字符串为1MB,并且在其中发现替换字符100次,那么这就意味着只为100字节分配100MB的内存。
std::string result = boost::replace_all_copy(origStr , subStringToRemove , subStringToReplace);
void            Replace::replace(std::string & str, std::string const & s1, std::string const & s2)
{
    size_t      pos;

    pos = 0;
    while ((pos = str.find(s1, pos)) != std::string::npos)
    {
        str.erase(pos, s1.length());
        str.insert(pos, s2);
        pos += s2.length();
    }
    return ;
}
std::string const result = std::regex_replace( chartDataString, std::regex( "\\*A" ), "[A]\n" );
int len=del.length();
string output="[Programming Error]";
if(line.find(del)!=-1){
    do{
        output=line.replace(line.find(del),len,replace);
    }while(output.find(del)!=-1);
}
return output;