使用 (Core)Foundation 折叠/规范化连字(例如 Æ 到 ae)

2023-11-28

我正在编写一个助手,它对输入字符串执行多次转换,以便创建该字符串的搜索友好表示。

考虑以下场景:

  • 德语或法语文本全文搜索
  • The entries in your datastore contain
    1. Müller
    2. Großmann
    3. Çingletòn
    4. Bjørk
    5. Æreogramme
  • The search should be fuzzy, in that
    1. ull, Üll等等匹配Müller
    2. Gros, groß等等匹配Großmann
    3. cin等等匹配Çingletòn
    4. bjö, bjo等等匹配Bjørk
    5. aereo等等匹配Æreogramme

到目前为止,我已经成功解决了案例(1)、(3)和(4)。

我不明白的是如何处理(2)和(5)。

到目前为止,我已经尝试了以下方法,但没有效果:

CFStringNormalize() // with all documented normalization forms
CFStringTransform() // using the kCFStringTransformToLatin, kCFStringTransformStripCombiningMarks, kCFStringTransformStripDiacritics
CFStringFold() // using kCFCompareNonliteral, kCFCompareWidthInsensitive, kCFCompareLocalized in a number of combinations -- aside: how on earth do I normalize simply _composing_ already decomposed strings??? as soon as I pack that in, my formerly passing tests fail, as well...

我浏览过ICU 变换用户指南但并没有投入太多......出于我认为显而易见的原因。

我知道我可以通过转换为大写然后再转换回小写来捕获情况 (2),这将在这个特定应用程序的范围内工作。然而,我有兴趣在更基础的层面上解决这个问题,希望也允许区分大小写的应用程序。

任何提示将不胜感激!


恭喜,您已经发现了文本处理中最痛苦的部分之一!

首先,姓名列表.txt and 案例折叠.txt如果您还没有看过的话,它们是此类事物不可或缺的资源。

部分问题在于你正在尝试做某事几乎正确它适用于您关心的所有语言/区域设置,而 Unicode 更关心在单一语言区域设置中显示字符串时执行正确的操作。

对于(2),ß已规范地大小写折叠为ss自从我能找到最早的 CaseFolding.txt (3.0-Update1/CaseFolding-2.txt). CFStringFold() and -[NSString stringByFoldingWithOptions:]应该做正确的事情,但如果不正确,则“独立于语言环境”s.upper().lower()似乎对所有输入给出了合理的答案(并且还处理了臭名昭著的“土耳其语 I”)。

对于 (5),你有点运气不好:Unicode 6.2 似乎不包含从 Æ 到 AE 的规范映射,并且已从“字母”更改为“连字”并再次更改回来(U+00C6 是LATIN CAPITAL LETTER A E在1.0中,LATIN CAPITAL LIGATURE AE在 1.1 中,以及LATIN CAPITAL LETTER AE在 2.0 中)。您可以在 NamesList.txt 中搜索“连字”并添加一堆特殊情况。

Notes:

  • CFStringNormalize()不做你想做的事。你do想要在将字符串添加到索引之前对其进行规范化;我建议在其他处理的开始和结束时使用 NFKC。
  • CFStringTransform()也没有完全达到你想要的效果;所有脚本都是“拉丁文”
  • CFStringFold()是顺序相关的:组合ypogegrammeni 和 progegrammeni被剥夺kCFCompareDiacriticInsensitive但转换为小写iotakCFCompareCaseInsensitive。 “正确”的做法似乎是先进行案例折叠,然后再进行其他操作,尽管剥离它可能在语言上更有意义。
  • 您几乎肯定不想使用kCFCompareLocalized除非您想在每次区域设置更改时重建搜索索引。

其他语言的读者请注意:检查您使用的功能是否是not取决于用户当前的区域设置! Java 用户应该使用类似的东西s.toUpperCase(Locale.ENGLISH), .NET 用户应该使用s.ToUpperInvariant()。如果您确实想要用户当前的区域设置,请明确指定它。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 (Core)Foundation 折叠/规范化连字(例如 Æ 到 ae) 的相关文章

随机推荐

  • 使用 apache cordova 构建 Android 应用程序时出错

    我已经在 linux mint 17 1 xfce jdk 和 android 上安装了 cordova npm 没问题 我可以创建新的 cordova 应用程序并向其添加 android 平台 科尔多瓦创造 cordova平台添加andr
  • 验证引导模式中的输入文本

    我想在不使用任何框架的情况下验证引导模式中的表单 它实际上是一个简单的模式 只有一个输入文本和两个按钮 关闭 和 发送 用户应在输入框中输入他 她的姓名 然后单击发送 表单是通过 post 方法发送的 我想要做的是 如果用户没有在输入框中输
  • C# 字段与属性[重复]

    这个问题在这里已经有答案了 可能的重复 C 中属性和字段的区别 我认为基本属性 get set 与公共字段相同 唯一的优点是能够在不破坏二进制兼容性的情况下更改它们 按照我在这里得到的答案https stackoverflow com a
  • 基于 FLEX 的应用程序的自动化测试

    建议使用哪些工具 最好是开源工具 在基于 FLEX 的 Web 应用程序上驱动自动化测试套件 如果同一工具还具有驱动 Web 服务的内置功能 那就太好了 Adobe 自己分发了一个测试框架 FlexUnit
  • 如何在 C# 中删除被另一个进程锁定的文件?

    我正在寻找一种方法来删除被另一个进程使用 C 锁定的文件 我怀疑该方法必须能够找到哪个进程正在锁定文件 也许通过跟踪句柄 尽管我不确定如何在 C 中执行此操作 然后在能够使用以下命令完成文件删除之前关闭该进程File Delete 杀死其他
  • Google 表格中的日期时间和时区?

    我想计算 Google 表格中不同时区的日期时间之间的时差 如果我将两个字段格式化为 日期时间 另一个字段格式化为 持续时间 我可以使用差异运算符成功计算同一时区内的差异 Example A1 1 10 2016 10 10 00 B2 1
  • Langford 序列实现 Haskell 或 C

    在组合数学中 兰福德配对 也称为 Langford 序列 是以下序列的排列2n数字1 1 2 2 n n 其中两个 1 相距 1 个单位 两个 2 相距 2 个单位 更一般地 每个数字 k 的两个副本相距 k 个单位 例如 兰福德配对n 3
  • Java 正则表达式线程安全吗?

    我有一个使用的函数Pattern compile and a Matcher在字符串列表中搜索模式 该函数在多线程中使用 每个线程都会有一个唯一的模式传递给Pattern compile当线程被创建时 线程和模式的数量是动态的 这意味着我可
  • 读取多个文件并根据用户输入计算平均值

    我正在尝试在 R 中编写一个需要 3 个输入的函数 目录 污染物 id 我的计算机上有一个目录 里面充满了 CSV 文件 即超过 300 个 该函数的功能如下所示 pollutantmean lt function directory po
  • 调用同步 xm​​lhttprequest 时 IE 挂起 5 分钟

    我有一个 Web 应用程序 并使用 ajax 回调我的网络服务器来获取数据 有时 在相当不可预测的时刻 但可以重现 IE 完全挂起 5 分钟 窗口显示 未响应 然后返回 xmlhttprequest 对象响应错误 12002 我可以重现它的
  • 点击NSView

    我有一个NSView包含多个子视图 其中一个子视图是透明的并分层在顶部 我需要能够点击这个视图到下面的子视图 以便下面的视图获得第一响应者状态 但是所有鼠标事件都卡在顶部视图上 alpha 是1 因为我在里面画了东西 所以它应该只点击透明区
  • 更改滚动条上的 div 高度

    我想要的是顶部 标题 的 div 当您第一次加载页面时 它将处于最大高度 50px 当您向下滚动页面时 我希望高度平滑地降低到 30px 的最小高度 我猜我应该使用 jQuery 但我没有那么丰富的经验 所以我现在不知道解决方案 这是我当前
  • Angular 2 - 如何在 addEventListener 处理函数内调用打字稿函数?

    我正在尝试在添加到页面跨度的处理程序函数内调用另一个打字稿函数 任何类型 当我这样做时 处理函数工作正常 并且会执行基本的操作 例如设置变量 console log 等 但是 当尝试调用任何类型的函数时 它会抛出 无法读取未定义的属性 fu
  • 如何在 PHP 中更好地使用 Smarty?

    我发现在 PHP 中使用 Smarty 有时需要花费额外的时间 1 使用与 PHP 本身完全不同的语法2 需要检查小案例 因为文档没有提供更详细的细节 例如 逃逸 http www smarty net manual en language
  • 是否可以从 C++ 中的模板类型获取 char* 名称

    我想获取模板类型的字符串名称 const char 不幸的是我无法访问 RTTI template lt typename T gt struct SomeClass const char GetClassName const return
  • 如何增加 Flutter 中特定列表项的计数器?

    就像下面的示例图片一样 我想在单击单个列表项的按钮时增加或减少数量 如果我增加 setState 中的计数器 它会在每个列表项中递增 我需要这方面的帮助 特别是在处理 Flutter 中的特定列表项时 示例图片 2 任何帮助表示赞赏 提前致
  • 更新 ElasticSearch 设置中的分析器

    我正在使用 Sense Chrome 插件 并且我已经成功设置了一个分析器并且它工作正常 如果我对设置发出 GET media settings 则会返回以下内容 media settings index creation date 142
  • 如何将 console.log 写入文件

    现在我使用以下方式显示信息 console log kraken id markets 但是 我想将所有发送到控制台的信息写入文件中 如何通过完成以下代码来完成此操作 use strict var ccxt require ccxt asy
  • 我可以限制通用堆栈的深度吗?

    是否有内置方法来限制 System Collection Generics Stack 的深度 那么 如果您处于最大容量 推入新元素会删除堆栈的底部吗 我知道我可以通过转换为数组并重建堆栈来做到这一点 但我认为可能已经有一个方法了 编辑 我
  • 使用 (Core)Foundation 折叠/规范化连字(例如 Æ 到 ae)

    我正在编写一个助手 它对输入字符串执行多次转换 以便创建该字符串的搜索友好表示 考虑以下场景 德语或法语文本全文搜索 The entries in your datastore contain M ller Gro mann inglet