【问题标题】:Checking if a string contains a substring, regardless of capitalization检查字符串是否包含子字符串,无论大小写如何
【发布时间】:2016-03-01 05:44:46
【问题描述】:

假设我有一些字符串,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”子字符串。我可以通过某种论点来忽略大写吗?还是我应该完全使用其他东西?

【问题讨论】:

  • 最简单的解决方案是将两者转换为相同的大小写,但这可能不是最有效的。
  • 如果您打算处理 The World 的语言(而不仅仅是英语),您需要注意在每个字符上调用 toupper(或 tolower)和实际上是有区别的将整个字符串转换为大写(或小写)。请参阅this answer to a vaguely related question

标签: c++ string parsing substring


【解决方案1】:

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

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()like:

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

【讨论】:

    【解决方案2】:

    有多种选择。

    Using boost::algorithm::ifind_first.

    首先包括&lt;boost/algorithm/string/find.hpp&gt;&lt;string&gt;

    然后使用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()所建议的那样。

    【讨论】:

    • 我看不出这里的特征可以处理 UTF-8。
    猜你喜欢
    • 2011-03-31
    • 2015-07-18
    • 2011-11-09
    • 2013-05-18
    • 2011-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-20
    相关资源
    最近更新 更多