Reputation: 73
I need to replace a substring in a string. For example:
Input:
Always
Never
I will always run. ALWAYS!
Output:
I will never run. NEVER!
replace
and find
work fine. However, the problem is the case sensitive. I have this simple function to do that, but this is incomplete.
string subTag(string s,string a,string b)
{
while(s.find(a)!=-1){
s.replace(s.find(a), a.size(), b);
}
return s;
}
How can I make the search process case insensitive?
Upvotes: 1
Views: 3311
Reputation: 106
If you want to replace all substrings, consider the following algorithm.
It avoids infinite loops for calls like "subTag( "T_T", "t", "ttt" );"
std::string subTag( std::string s, std::string a, const std::string& b )
{
if( a.empty() )
return s;
std::string res = s;
std::transform( s.begin(), s.end(), s.begin(), ::tolower );
std::transform( a.begin(), a.end(), a.begin(), ::tolower );
size_t pos = s.rfind( a );
while( pos != std::string::npos )
{
res.replace( res.begin() + pos, res.begin() + pos + a.length(), b );
if( pos == 0 )
return res;
pos = s.rfind( a, pos - 1 );
}
return res;
}
Upvotes: 0
Reputation: 20284
Convert both the original string and the search phrase to lower case, then search:
string subTag(string s,string a,string b){
std::string lower_s;
std::transform(s.begin(), s.end(), lower_s.begin(), ::tolower);
std::transform(a.begin(), a.end(), a.begin(), ::tolower);
auto position=lower_s.find(a);
while(position!=std::string::npos){
s.replace(position, a.size(), b);
position=lower_s.find(a);
}
return s;
}
Notes:
s
since you need to return it without changing its case.a
directly since you are not using it anymore.b
since you are not using it to search at all.Upvotes: 3
Reputation: 1631
With c++11, try sth like this:
string subTag(string s,string a, string b)
{
auto pos = std::search(s.begin(), s.end(), a.begin(), a.end(), [](const char c1, const char c2){ return (std::tolower(c1)) == (std::tolower(c2));});
if(pos == s.end())
return "";
auto pos2 = pos;
std::cout << *pos << std::endl;
std::advance(pos2, a.size());
s.replace(pos, pos2, b);
return s;
}
Upvotes: 2