c ++:搜索忽略重音字符
Posted
技术标签:
【中文标题】c ++:搜索忽略重音字符【英文标题】:c++: search ignoring accented characters 【发布时间】:2017-12-05 21:48:44 【问题描述】:所以...我有一个 STL 向量,需要使用用户提供的字符串进行搜索/过滤。 (仅提及这一点,以防在此特定用例中有特定/更好的方法)
目前(此代码是旧)它只是通过迭代它并通过正则表达式匹配每个元素以查看它是否匹配来完成。
然而,我们的问题源于重音字符。我们期望的行为是搜索匹配字符串而不考虑变音符号(即“telefono”也匹配“teléfono”,反之亦然)
有没有一种体面的方法可以做到这一点,理想情况下不必求助于 boost 以外的库?
【问题讨论】:
Change all accented letters to normal letters in C++的可能重复 我不认为我的问题真的是重复的。我的意思是,我曾想过将其作为备用计划,但这并不是我真正想要做的。 我想这不是 true 副本,但您绝对可以将它用作解决方案的一部分。 你使用什么编码? 我们使用的是 UTF-8。 【参考方案1】:在询问有关字符串匹配(即 UTF-8 等)的问题时,了解字符编码是很有帮助的。也就是说,处理变音符号时的一种方法是在处理字符串之前将它们替换为等价的纯字符比较。您的匹配数据库将不包含任何变音符号,并且您将在比较之前清理您的搜索输入字符串。
【讨论】:
就像我上面说的,这将是我的 B 计划。这是一个歌曲列表(艺术家/标题),所以我想保留变音符号以供显示。我想可能会在我们的结构中添加几个成员来表示艺术家和标题的净化版本(有点像 iTunes 所做的),但如果可能的话,我想避免这种方法。【参考方案2】:简短回答:您“标准化”两个字符串,然后进行搜索/比较。
请注意,Unicode 以不止一种方式表示许多重音字符。有一个单独的代码点(U+00E9 LATIN SMALL E WITH ACUTE ACCENT)来表示带有重音的字符,但也可以用代码点的组合来表示(U+0065 LATIN SMALL LETTER E 和 U+0301 COMBINING ACUTE ACCENT) )。处理这种情况的一般方法是选择一种范式 C(用于预组合字符)或 D(用于分解字符)。规范化可能比看起来更复杂。一旦两个字符串的范式相同,就可以直接比较。
如果您想完全忽略变音符号,您可以制定自己的规范化方案。例如,您可以分解任何预先组合的字符,然后删除所有组合代码点。这将允许基字符匹配重音字符,而不管重音字符最初是如何表示的。
Unicode 中也有“兼容性”范式(KC 和 KD),它们用最常见的相似基本字符替换大多数特殊字符。在变音符号的情况下,我认为这会做同样的事情。因此,如果您有一个 Unicode 库,您也许可以使用它来完成所有繁重的规范化工作。
在很多情况下,数据库已经是一些正常的形式,所以你只需要规范化搜索字符串。
如果这一切都太复杂了,另一种方法是构建一个匹配任何表示的正则表达式。例如,如果您的搜索关键字是telefono
,您可以将其转换为像t(e|\u00E9|e\u0301)l(e|\u00E9|e\u0301)f(o|\u00F3|o\u0301)n(o|\u00F3|o\u0301)
这样的正则表达式。这些正则表达式可能非常庞大,具体取决于您希望匹配的灵活性。
【讨论】:
它需要灵活,因为它基本上是一个歌曲列表,搜索是用户输入,所以它几乎可以是任何东西。我刚刚意识到我可以使用 ICU,因为我们应用程序中的其他东西已经依赖于它,所以它不会添加更多依赖项。不过,我得弄清楚该怎么做。以上是关于c ++:搜索忽略重音字符的主要内容,如果未能解决你的问题,请参考以下文章