检查字符串是否包含子字符串,而不管大小写

时间:2015-11-27 04:35:56

标签: c++ string parsing substring

假设我有一些字符串str。

我要检查str是否包含关键字:“samples” 但是,“样本”可以采用任何形式的大写形式,例如:“样本”“SamPleS”,“样本”。

这就是我想要的:

string str = "this is a FoO test";
if (str.find("foo") != std::string::npos){
    std::cout << "WORKS";
}

这不会检测到“FoO”子字符串。我可以通过某种论证来忽略大写吗?或者我应该完全使用其他东西吗?

2 个答案:

答案 0 :(得分:4)

将两个字符串转换为大写:

std::string upperCase(std::string input) {
  for (std::string::iterator it = input.begin(); it != input.end(); ++ it)
    *it = toupper((unsigned char)*it);
  return input;
}

然后使用find(),如:

upperCase(str).find(upperCase(target))

答案 1 :(得分:1)

有多种选择。

Using boost::algorithm::ifind_first

首先包括<boost/algorithm/string/find.hpp><string>

然后使用ifind_first,如下所示。

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;

然后您可以按如下方式使用它。

ci_string str = ...;
std::string subStr = ...;
auto pos = str.find(subStr.c_str());

请注意,问题在于,您需要在调用find函数时或在将ci_string分配给std :: string或将std :: string分配给ci_string时使用c_str函数。

std::search与自定义谓词

一起使用

正如文章Case insensitive std::string.find()中所建议的那样。