使用locale在字符串中查找子字符串

时间:2013-09-26 07:30:19

标签: c++ string mfc std

我需要查找字符串是否包含子字符串,但是根据当前语言环境的规则。

所以,如果我正在搜索字符串“aba”,使用西班牙语语言环境,“cabalgar”,“rábano”和“gabán”都会包含它。

我知道我可以将字符串与区域设置信息(整理)进行比较,但是有没有内置或星际向前的方式来执行相同的查找,或者我是否必须自己编写?

我可以使用std :: string(最多TR1)或MFC的CString

3 个答案:

答案 0 :(得分:2)

作为参考,这里是使用使用ICU后端编译的boost语言环境的实现:

#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

答案 1 :(得分:1)

您可以循环遍历字符串索引,并将子字符串与您要查找的字符串std::strcoll进行比较。

答案 2 :(得分: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";
}

然而,正如你所看到的......这不符合你的要求。请参阅您问题的评论。