【问题标题】:Why boost locale didn't provide character level rule type?为什么 boost locale 没有提供字符级规则类型?
【发布时间】:2014-12-29 02:43:58
【问题描述】:

环境:boost1.53.0 c++11;

C++ 新手。

在 boost locale 边界分析中,为 word(eg.boundary::word_letter,boundary::word_number) 和 sentence 指定了规则类型,但没有为字符指定边界规则类型。我想要的只是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++ 中却如此令人困惑?有什么方法可以实现这些吗?

【问题讨论】:

  • “boost string algorithm which didn't work”是什么意思,你的程序崩溃了?
  • = =!它没有按预期工作。结果错误。它只能处理 ascii 字母。再次感谢~
  • 哪个操作系统?您的源文件保存在哪个代码页中?
  • unbuntu 12.04。一切都用 utf8 编码。
  • 看看问题中的程序,stackoverflow.com/questions/27614666/…。与您正在尝试的非常相似,并且效果很好。只需根据您的程序更改它,当然更改语言环境,看看它是否有效

标签: c++ c++11 boost


【解决方案1】:

这在 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());

【讨论】:

  • 它终于对我有用了。事实上,这是我的命名实体标记项目的一部分。从句子分割、分词到命名实体标注,整个流水线统一在unicode string,基本字符单元是一个utf8 char。并且根据stackoverflow.com/questions/402283/stdwstring-vs-stdstringwstring 在 windows 下是首选,但在 linux 下不是。无论如何,如果没有其他选择,那么它必须是这样。感谢您所做的一切!
  • 我发布了另一种方法来实现这一目标。有兴趣可以看看。
【解决方案2】:

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 %s\n", p, type.c_str());
    p= bi->next();
}
delete bi;
return 0;

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-01-23
    • 1970-01-01
    • 2020-10-12
    • 2016-06-10
    • 1970-01-01
    • 1970-01-01
    • 2012-10-19
    • 2014-03-19
    相关资源
    最近更新 更多