2013-09-26 4 views
2

Мне нужно найти, если строка содержит подстроку, но в соответствии с правилами текущей локали.Найти подстроку в строке с использованием locale

Итак, если я ищу строку «aba», с испанским языком, «cabalgar», «rábano» и «gabán», все три будут содержать это.

Я знаю, что могу сравнивать строки с информацией о локали (сопоставить), но есть ли какой-либо встроенный или звездный способ сделать то же самое с find, или мне нужно написать свой собственный?

Я в порядке, используя зЬй :: строки (до TR1) или МЦА CString

+0

Вы должны написать свой собственный (или получить третья сторона, чтобы сделать это для вы). – john

+0

Это было мое предположение ... – MikMik

+0

Возможно, релевантно: http://stackoverflow.com/a/144804/85371 и Boost Locale (http://www.codeproject.com/Questions/595935/Howplustopluscompareplusunicodeplusstringsplusigno) – sehe

ответ

1

Вы могли бы перебирает строковые индексы, и сравнить подстроку строки, которую вы хотите найти с std::strcoll.

1

Я не использовал это раньше, но 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"; 
} 

Однако, как вы можете видеть ... Это не делает то, что вы хотите. См. Комментарий по вашему вопросу.

2

Для справки, здесь является реализация с использованием подталкивание локаль скомпилирован с 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 
Смежные вопросы