不区分大小写的字符串查找

7

是否存在一个不区分大小写的find()方法适用于std::string


3
"case insensitive"的含义取决于情境。您只使用ASCII字符,还是需要全Unicode排序? - Philipp
5个回答

14

你可以将两个字符串都转换为大写,然后使用普通的查找函数。(注意:如果你有Unicode字符串,这种方法可能不正确。)

在Boost中还有一个针对大小写不敏感搜索的ifind_first函数(请注意它返回一个范围而不是一个size_t值)。

#include <string>
#include <boost/algorithm/string/find.hpp>
#include <cstdio>
#include <cctype>

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

int main () {
  std::string foo = "1 FoO 2 foo";
  std::string target = "foo";

  printf("string.find: %zu\n", foo.find(target));

  printf("string.find w/ upperCase: %zu\n", upperCase(foo).find(upperCase(target)));

  printf("ifind_first: %zu\n", boost::algorithm::ifind_first(foo, target).begin() - foo.begin());

  return 0;
}

我刚试用了ifind_first,但它比将两个字符串转换为小写(使用boost)并使用std::string::find要慢。 - goji
但是在一般情况下,它不能处理Unicode。 "ß"和"SS"应该相等,但Boost字符串算法无法处理这种情况。 - dalle
@dalle:在这种情况下,您应该使用Unicode库,例如libicu(在这些情况下,您可能需要一个区域设置来了解土耳其语中的İ)。 - kennytm
是的,很可能。太遗憾了,C++标准库不支持Unicode。 - dalle

5
这是我建议的内容(与@programmersbook相同)。
#include <iostream>
#include <algorithm>
#include <string>

bool lower_test (char l, char r) {
  return (std::tolower(l) == std::tolower(r));
}

int main()
{
  std::string text("foo BaR");
  std::string search("bar");

  std::string::iterator fpos = std::search(text.begin(), text.end(), search.begin(), search.end(), lower_test);
  if (fpos != text.end())
    std::cout << "found at: " << std::distance(text.begin(), fpos) << std::endl;
  return 0;
}

3

0
for(int i=0; i<yourString.length() 
    && tolower(yourString[i])!=yourLoweredChar; i++)
{
    return i;
}
return -1;

如果返回-1,则表示目标字符不存在。
否则,返回该字符的第一个出现位置。

0

最高效的方式

性能保证是线性的,初始化成本为2 * NEEDLE_LEN比较。(glic)

#include <cstring>
#include <string>
#include <iostream>

int main(void) {

    std::string s1{"abc de fGH"};
    std::string s2{"DE"};

    auto pos = strcasestr(s1.c_str(), s2.c_str());

    if(pos != nullptr)
        std::cout << pos - s1.c_str() << std::endl;

    return 0;
}

strcasestr 不是标准的 C++ 的一部分。 - Evg
@Evg.当然可以。但是你可以在Windows上使用StrStrIA,并且加上#pragma comment(lib,"shlwapi.lib") - Delta

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