Checking if a string contains a substring, regardless of capitalization
Solution 1
Convert both the strings to upper case :
std::string upperCase(std::string input) {
for (std::string::iterator it = input.begin(); it != input.end(); ++ it)
*it = toupper((unsigned char)*it);
return input;
}
Then use find()
like :
upperCase(str).find(upperCase(target))
Solution 2
There are a variety of options.
Using boost::algorithm::ifind_first.
First include <boost/algorithm/string/find.hpp>
and <string>
.
Then use ifind_first
as follows.
std::string str = ...;
std::string subStr = ...;
boost::iterator_range<std::string::const_iterator> rng;
rng = boost::ifind_first(str, subStr);
Using char_traits.
struct ci_char_traits : public char_traits<char>
{
static bool eq(char c1, char c2) { return toupper(c1) == toupper(c2); }
static bool ne(char c1, char c2) { return toupper(c1) != toupper(c2); }
static bool lt(char c1, char c2) { return toupper(c1) < toupper(c2); }
static int compare(const char* s1, const char* s2, size_t n)
{
while( n-- != 0 )
{
if( toupper(*s1) < toupper(*s2) ) return -1;
if( toupper(*s1) > toupper(*s2) ) return 1;
++s1; ++s2;
}
return 0;
}
static const char* find(const char* s, int n, char a)
{
while(n-- > 0 && toupper(*s) != toupper(a))
{
++s;
}
return s;
}
};
typedef std::basic_string<char, ci_char_traits> ci_string;
Then you can use it as follows.
ci_string str = ...;
std::string subStr = ...;
auto pos = str.find(subStr.c_str());
Note that the problem with this is the fact that you need to use the c_str function when calling the find function or when assigning a ci_string to a std::string or when assigning a std::string to a ci_string.
Use std::search
with a custom predicate
As suggested in the article Case insensitive std::string.find().
Hani Al-shafei
Updated on June 04, 2022Comments
-
Hani Al-shafei almost 2 years
Suppose I have some string, str.
I was to check if str contains a keyword: "samples" However, "samples" could be in any form of capitalization such as: "Samples" "SamPleS", "SAMPLES".
this is what I am trying:
string str = "this is a FoO test"; if (str.find("foo") != std::string::npos){ std::cout << "WORKS"; }
This does not detect the "FoO" substring. Is there some sort of argument I can pass through to ignore capitalization? Or should I be using something else entirely?