检查字符串是否包含子字符串,无论大小写

3

假设我有一个字符串 str。

我想要检查 str 是否包含关键字:“samples”。 但是,“samples”可以以任何大小写形式出现,例如:“Samples”、“SamPleS”、“SAMPLES”。

这是我尝试的代码:

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

这并不能检测到 "FoO" 子字符串。我能否通过某种参数进行忽略大小写的操作?或者我应该完全使用其他东西?

最简单的解决方案是将两者转换为相同的大小写,但这可能不是最有效的方法。 - Neil Kirk
如果你打算处理世界上的语言(而不仅仅是英语),你需要意识到在每个字符上调用 toupper(或 tolower)和实际将整个字符串转换为大写(或小写)之间存在区别。请参阅这个与问题有点关联的答案 - rici
1个回答

1

有多种选择。

使用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);

使用 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,如不区分大小写的std :: string.find()文章中建议的那样。

我看不出这里的特性东西如何处理UTF-8。 - Cheers and hth. - Alf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接