c++ - 使用 ICU 将文本拆分为单词列表

标签 c++ utf-8 icu

我正在研究文本分词器。 ICU 是为数不多的具有此功能的 C++ 库之一,而且可能是维护得最好的一个,因此我想使用它。 我找到了有关 BreakIterator 的文档,但它有一个问题:如何去掉标点符号?

#include "unicode/brkiter.h"

#include <QFile>

#include <vector>

std::vector<QString> listWordBoundaries(const UnicodeString& s)
{
    UErrorCode status = U_ZERO_ERROR;
    BreakIterator* bi = BreakIterator::createWordInstance(Locale::getUS(), status);

    std::vector<QString> words;

    bi->setText(s);
    for (int32_t p = bi->first(), prevBoundary = 0; p != BreakIterator::DONE; prevBoundary = p, p = bi->next())
    {
        const auto word = s.tempSubStringBetween(prevBoundary, p);
        char buffer [16384];
        word.toUTF8(CheckedArrayByteSink(buffer, 16384));
        words.emplace_back(QString::fromUtf8(buffer));
    }

    delete bi;

    return words;
}

int main(int /*argc*/, char * /*argv*/ [])
{
    QFile f("E:\\words.TXT");
    f.open(QFile::ReadOnly);

    QFile result("E:\\words.TXT");
    result.open(QFile::WriteOnly);

    const QByteArray strData = f.readAll();
    for (const QString& word: listWordBoundaries(UnicodeString::fromUTF8(StringPiece(strData.data(), strData.size()))))
    {
        result.write(word.toUtf8());
        result.write("\n");
    }

    return 0;
}

自然地,生成的文件看起来像这样:

“
Come

outside
.

Best

if

we

do

not

wake

him
.
”

我需要的只是文字。如何做到这一点?

最佳答案

QT 库包括几个有用的方法来检查字符的属性: QChar .

实际上,您可以从缓冲区 创建QString 变量 并在插入输出 vector 之前检查您需要的所有属性。

例如:

auto token = QString::fromUtf8(buffer);
if (token.length() > 0 && token.data()[0].isPunct() == false) {
  words.push_back(std::move(token));
}

使用该代码,我可以访问字符串的第一个字符并检查 是否为标点符号。

更强大的东西,我将其表示为函数:

bool isInBlackList(const QString& str) {
  const auto len = str.lenght();
  if (len == 0) return true;
  for(int i = 0; i < len; ++i) {
    const auto&& c = str.data()[i];
    if (c.isPunct() == true || c.isSpace() == true) {
      return true;
    }
  }
  return false;
}

如果该函数返回 true,则标记没有被插入到 vector 中。

关于c++ - 使用 ICU 将文本拆分为单词列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38824296/

相关文章:

c++ - 为什么 unsigned int 0xFFFFFFFF 等于 int -1?

c++ - 两种不同的编译器配置之间可能会丢失精度

php - php 和 sql 中的土耳其语字符

c++ - 您能否访问 ICU MessageFormat 使用的 NumberFormatter

c++ - 使用 boost::locale 进行 Unicode 字符分类

c++ - 创建一个基于所选选项卡选择主菜单栏的功能

c++ - 提升精神规则-规则串联

java - 在 Java 中将 bytes 转换为 String 时会发生什么?

.htaccess - &lt;meta http-equiv ="Content-Type"content="text/html; charset=utf-8> 的 htaccess 等效项是什么

c++ - 如何使用带有 UTF-16 的 ICU?