Найти подстроку в строке, используя локаль
Мне нужно найти, если строка содержит подстроку, но в соответствии с правилами текущей локали.
Так что, если я ищу строку "aba" с испанскими языками, "cabalgar", "rábano" и "gabán" содержат все три.
Я знаю, что могу сравнивать строки с информацией о локали (collate), но есть ли какой-нибудь встроенный или простой способ сделать то же самое с find, или я должен написать свой собственный?
Я в порядке, используя std::string (до TR1) или CString MFC
3 ответа
Для справки, вот реализация, использующая улучшенный языковой стандарт, скомпилированный с бэкэндом ICU:
#include <iostream>
#include <boost/locale.hpp>
namespace bl = boost::locale;
std::locale usedLocale;
std::string normalize(const std::string& input)
{
const bl::collator<char>& collator = std::use_facet<bl::collator<char> >(usedLocale);
return collator.transform(bl::collator_base::primary, input);
}
bool contain(const std::string& op1, const std::string& op2){
std::string normOp2 = normalize(op2);
//Gotcha!! collator.transform() is returning an accessible null byte (\0) at
//the end of the string. Thats why we search till 'normOp2.length()-1'
return normalize(op1).find( normOp2.c_str(), 0, normOp2.length()-1 ) != std::string::npos;
}
int main()
{
bl::generator generator;
usedLocale = generator(""); //use default system locale
std::cout << std::boolalpha
<< contain("cabalgar", "aba") << "\n"
<< contain("rábano", "aba") << "\n"
<< contain("gabán", "aba") << "\n"
<< contain("gabán", "Âbã") << "\n"
<< contain("gabán", "aba.") << "\n"
}
Выход:
true
true
true
true
false
Вы можете перебрать строковые индексы и сравнить подстроку со строкой, с которой хотите найти std::strcoll
,
Я не использовал это раньше, но std::strxfrm
похоже, что вы могли бы использовать:
#include <iostream>
#include <iomanip>
#include <cstring>
std::string xfrm(std::string const& input)
{
std::string result(1+std::strxfrm(nullptr, input.c_str(), 0), '\0');
std::strxfrm(&result[0], input.c_str(), result.size());
return result;
}
int main()
{
using namespace std;
setlocale(LC_ALL, "es_ES.UTF-8");
const string aba = "aba";
const string rabano = "rábano";
cout << "Without xfrm: " << aba << " in " << rabano << " == " <<
boolalpha << (string::npos != rabano.find(aba)) << "\n";
cout << "Using xfrm: " << aba << " in " << rabano << " == " <<
boolalpha << (string::npos != xfrm(rabano).find(xfrm(aba))) << "\n";
}
Однако, как вы можете видеть... Это не делает то, что вы хотите. Смотрите комментарий на ваш вопрос.