c ++:搜索忽略重音字符

时间:2017-12-05 21:48:44

标签: c++ regex boost unicode internationalization

所以...我有一个STL向量,我需要使用用户提供的字符串进行搜索/过滤。 (只是在这个特定用例中有一个特定/更好的方法来提及这个)

目前(此代码)只需迭代它并正则表达式匹配每个元素以查看它是否匹配。

然而,我们的问题源于重音字符。我们期望的行为是搜索匹配字符串而不考虑变音符号(即“telefono”也匹配“teléfono”,反之亦然)

有没有一个像样的方法来做到这一点,理想情况下,不必诉诸除了推动以外的图书馆?

2 个答案:

答案 0 :(得分:0)

在询问有关字符串匹配的问题(即UTF-8等)时,了解字符编码是有帮助的。据说,在处理变音符号时,其中一种方法是在执行字符串之前将它们替换为普通字符等价物相比。您的匹配数据库不包含任何变音符号,您将在比较之前清理搜索输入字符串。

答案 1 :(得分:0)

简短回答:你"正常化"两个字符串然后进行搜索/比较。

请注意,Unicode以多种方式表示许多重音字符。有一个代码点(U + 00E9 LATIN SMALL E WITH ACUTE ACCENT)来表示带重音的字符,但它也可以用代码点组合表示(U + 0065 LATIN SMALL LETTER E和U + 0301 COMETINING ACUTE ACCENT )。解决这个问题的一般方法是选择一个普通形式C(对于预先组成的字符)或D(对于去组合字符)。规范化可能比看起来更复杂。一旦两个字符串处于相同的正常形式,您就可以直接比较它们。

如果你想完全忽略变音符号,你可以编写自己的归一化方案。例如,您可以分解任何预先组合的字符,然后删除所有组合代码点。无论最初如何表示重音字符,都将允许基本字符匹配重音字符。

还有" kompatibility" 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)等正则表达式。这些正则表达式可能非常快,取决于您希望匹配的灵活性。