在c++中进行不区分大小写字符串比较而不将字符串转换为全大写或全小写的最佳方法是什么?
请指出这些方法是否对unicode友好,以及它们的可移植性如何。
在c++中进行不区分大小写字符串比较而不将字符串转换为全大写或全小写的最佳方法是什么?
请指出这些方法是否对unicode友好,以及它们的可移植性如何。
当前回答
str1.size() == str2.size() && std::equal(str1.begin(), str1.end(), str2.begin(), [](auto a, auto b){return std::tolower(a)==std::tolower(b);})
如果你不能使用boost,你可以在c++ 14中使用上面的代码。对于宽字符,必须使用std::towlower。
其他回答
str1.size() == str2.size() && std::equal(str1.begin(), str1.end(), str2.begin(), [](auto a, auto b){return std::tolower(a)==std::tolower(b);})
如果你不能使用boost,你可以在c++ 14中使用上面的代码。对于宽字符,必须使用std::towlower。
假设您正在寻找一个方法,而不是一个已经存在的神奇函数,坦率地说,没有更好的方法。对于有限的字符集,我们都可以使用聪明的技巧编写代码片段,但在一天结束时,你必须转换字符。
这种转换的最佳方法是在比较之前进行转换。当涉及到编码方案时,这为您提供了很大的灵活性,而实际的比较操作符应该忽略这一点。
当然,你可以在你自己的字符串函数或类后面“隐藏”这个转换,但你仍然需要在比较之前转换字符串。
看到std:: lexicographical_compare:
// lexicographical_compare example
#include <iostream> // std::cout, std::boolalpha
#include <algorithm> // std::lexicographical_compare
#include <cctype> // std::tolower
// a case-insensitive comparison function:
bool mycomp (char c1, char c2) {
return std::tolower(c1) < std::tolower(c2);
}
int main () {
char foo[] = "Apple";
char bar[] = "apartment";
std::cout << std::boolalpha;
std::cout << "Comparing foo and bar lexicographically (foo < bar):\n";
std::cout << "Using default comparison (operator<): ";
std::cout << std::lexicographical_compare(foo, foo + 5, bar, bar + 9);
std::cout << '\n';
std::cout << "Using mycomp as comparison object: ";
std::cout << std::lexicographical_compare(foo, foo + 5, bar, bar + 9, mycomp);
std::cout << '\n';
return 0;
}
Demo
支持unicode的Visual c++字符串函数:http://msdn.microsoft.com/en-us/library/cc194799.aspx
您可能正在寻找的是_wcsnicmp
Boost::iequals在string的情况下不兼容utf-8。 你可以使用boost::locale。
comparator<char,collator_base::secondary> cmpr;
cout << (cmpr(str1, str2) ? "str1 < str2" : "str1 >= str2") << endl;
Primary -- ignore accents and character case, comparing base letters only. For example "facade" and "Façade" are the same. Secondary -- ignore character case but consider accents. "facade" and "façade" are different but "Façade" and "façade" are the same. Tertiary -- consider both case and accents: "Façade" and "façade" are different. Ignore punctuation. Quaternary -- consider all case, accents, and punctuation. The words must be identical in terms of Unicode representation. Identical -- as quaternary, but compare code points as well.