【问题标题】:Case insensitive search in Unicode in C++ on WindowsWindows 上 C++ 中 Unicode 中不区分大小写的搜索
【发布时间】:2010-12-09 17:27:57
【问题描述】:

我昨天问了一个类似的问题,但我意识到我需要以不同的方式重新调整它。

简而言之: 在 Windows 上的 C++ 中,当字符串为 unicode 格式(宽字符、wchar_t)并且我不知道字符串的语言时,如何对字符串(在另一个字符串内)进行不区分大小写的搜索。我只想知道大海捞针是否存在。针的位置与我无关。

背景: 我有一个包含大量电子邮件正文的存储库。消息使用不同的语言(日语、德语、俄语、芬兰语;您可以命名)。所有数据都是 Unicode 格式,我将它加载到我的 C++ 应用程序中的宽字符串 (wchar_t) 中(主体已被 MIME 解码,因此在我的调试器中我可以看到实际的日文、德文字符)。我不知道邮件的语言,因为电子邮件不包含该详细信息,而且单个电子邮件正文可能包含来自多种语言的字符。

我正在寻找类似 wcsstr 的东西,但它能够以不区分大小写的方式进行搜索。我知道在不了解文本语言的情况下,不可能 100% 正确地从大写字母转换为小写字母。我想要一个在 99% 的情况下都可行的解决方案。

我正在使用带有 C++、STL 和 Boost 的 Visual Studio 2008。

【问题讨论】:

  • 正如 Iiİı 问题所证明的那样,您希望忽略的不仅仅是大小写。您实际上想要一个不精确的匹配,例如您还想要 é=e。并且 æ=ae,因此您甚至不能逐个字符地执行此操作。

标签: c++ search unicode case-insensitive widestring


【解决方案1】:

您必须指定语言才能进行不区分大小写的比较。例如,在土耳其语中,“i”不是对应于“I”的小写字母。如果似乎未指定语言,则表示正在使用隐式选择的语言进行比较。

【讨论】:

  • 这次我的问题显然太长了。正如我在问题中指出的那样,我很清楚我需要了解语言才能 100% 正确地做到这一点。但由于这在技术上是不可能的,所以我要求一个在 99% 的时间都有效的解决方案。
  • 您要搜索的字符串的来源是什么?如果它们是由用户提供的,那么用户的语言环境可能是合适的。您的问题也没有解释为什么您认为需要不区分大小写的搜索。
【解决方案2】:

Boost String Algorithms 有一个 icontains() 函数模板,可以满足您的需求。

【讨论】:

  • 它适用于 wchar_t* 和 std::wstring 类型或任何派生自 std::basic_string.
  • 但在一般情况下它不适用于 Unicode。 "ß" 和 "SS" 应该比较相等,但 Boost 字符串算法不能处理这个问题。
【解决方案3】:

您应该使用ICU library,它为遵循Unicode 规则的Unicode 正则表达式提供支持以进行不区分大小写的匹配。该库以 C/C++ 和 Java 库的形式提供。许多其他语言(例如 Python)支持 ICU 库的包装器。

【讨论】:

  • 我不想仅仅为了这个而捆绑一个新的大型库。我正在寻找 Boost 或 Windows API 中可用的解决方案。
  • 我下载download.icu-project.org/files/icu4c/4.2.1/…查看,.lib文件加起来大约200K,DLL加起来大约20M。在当今时代,这并不多,而且您实际上可能并不需要所有这些来完成您的工作。无论如何,ICU 是处理 Unicode 的正确方法。
  • 考虑到我正在尝试做的事情的范围,ICU 解决的 Ferruccios 解决方案会出现什么问题?
  • icontains 文档说它仅在单个语言环境中处理不区分大小写的匹配。由于您正在处理多种语言的消息,因此它可能无法正常工作。当然,如果您在消息中记录了语言标识,那么您可以使用 icontains() 来完成。 ICU 是 UNICODE 文本操作的全面解决方案,当您可以将其应用于许多其他问题时,使用它会在未来得到回报。
  • 好吧,正如我在问题中提到的,我不知道消息的语言。而且由于理论上不可能在不了解语言的情况下进行 100% 正确的大小写转换,所以我仍然不明白 ICU 在 icontains 上添加了什么。对我来说,包含一个 20MB 的库来进行字符串搜索听起来很糟糕,因为将来某个时候我可能需要该 20MB 库中的其他部分。
【解决方案4】:

您可以将 needle 和 haystack 都转换为小写(或大写),然后执行 wcsstr()。

【讨论】:

    猜你喜欢
    • 2017-12-01
    • 1970-01-01
    • 2016-07-06
    • 1970-01-01
    • 1970-01-01
    • 2010-10-13
    • 2012-01-04
    • 2011-07-20
    • 2015-10-23
    相关资源
    最近更新 更多