为什么提升区域设置不提供字符级别规则类型?

Why boost locale didn't provide character level rule type?

本文关键字:规则 类型 字符 区域 设置 为什么      更新时间:2023-10-16

Env: boost1.53.0 c++11;

C++ 的新手。

在提升区域设置边界分析中,为 word(例如。boundary::word_letterboundary::word_number) 和句子,但没有字符的边界规则类型。我想要的只是像isUpperCase(), isLowerCase(), isDigit(), isPunctuation()这样的东西.

尝试了提升字符串算法,但不起作用。

boost::locale::generator gen;
std::locale loc = gen("ru_RU.UTF-8");
std::string context = "ДВ";
std::cout << boost::algorithm::all(context, boost::algorithm::is_upper(loc));

为什么这些功能可以在Java或Python中轻松访问,但在C++中却如此混乱?有什么办法可以实现这些目标吗?

这在VS 2013下对我有用。

locale::global(locale("ru-RU")); 
std::string context = "ДВ"; 
std::cout << any_of(context.begin(), context.end(), boost::algorithm::is_upper());

打印1

如何初始化区域设置非常重要。

更新:

这是可以在 Ubuntu 下工作的解决方案。

#include <iostream>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/locale.hpp>
using namespace std;
int main()
{
    locale::global(locale("ru_RU"));
    wstring context = L"ДВ";
    wcout << boolalpha << any_of(context.begin(), context.end(), boost::algorithm::is_upper());
    wcout<<endl;
    wstring context1 = L"ПРИВЕТ, МИР"; //HELLO WORLD in russian
    wcout << boolalpha << any_of(context1.begin(), context1.end(), boost::algorithm::is_upper());
    wcout<<endl;
    wstring context2 = L"привет мир"; //hello world in russian
    wcout << boolalpha << any_of(context2.begin(), context2.end(), boost::algorithm::is_upper());
    return 0;
}

指纹

true
true
false

这也适用于boost::algorithm::all。

wstring context = L"ДВ";
wcout << boolalpha << boost::algorithm::all(context, boost::algorithm::is_upper());

Boost.locale 基于 ICU,ICU 本身确实提供了字符级别分类,这看起来非常简单易读(更多是 Java 风格)。

下面是一个简单的示例。

#include <unicode/brkiter.h>
#include <unicode/utypes.h>
#include <unicode/uchar.h>
int main()
{
UnicodeString s("А аБ Д д2 -");
UErrorCode status = U_ERROR_WARNING_LIMIT;
Locale ru("ru", "RU");
BreakIterator* bi = BreakIterator::createCharacterInstance(ru, status);
bi->setText(s);
int32_t p = bi->first();
while(p != BreakIterator::DONE) {
    std::string type;
    if(u_isUUppercase(s.charAt(p)))
        type = "upper" ;
    if(u_isULowercase(s.charAt(p)))
        type = "lower" ;
    if(u_isUWhiteSpace(s.charAt(p)))
        type = "whitespace" ;
    if(u_isdigit(s.charAt(p)))
        type = "digit" ;
    if(u_ispunct(s.charAt(p)))
        type = "punc" ;
    printf("Boundary at position %d is %sn", p, type.c_str());
    p= bi->next();
}
delete bi;
return 0;

}