如何在标准 SQL 中使用 Unicode 规范化删除变音符号(例如重音符号)?

2024-05-08

如何使用新功能从 BigQuery 中的字符串中删除变音符号normalize https://cloud.google.com/bigquery/docs/reference/standard-sql/functions-and-operators#normalize函数如:

café

导致:

cafe

简短的回答

当你了解了 Normalize 的作用之后,其实就很简单了:

WITH data AS(
  SELECT 'Ãâíüçãõ' AS text
)

SELECT
  REGEXP_REPLACE(NORMALIZE(text, NFD), r'\pM', '') nfd_result,
  REGEXP_REPLACE(NORMALIZE(text, NFKD), r'\pM', '') nfkd_result
FROM data

Results:

Row   nfd_result    nfkd_result  
1     Aaiucao       Aaiucao  

您可以使用选项“NFD”或“NFKD”,并且在大多数情况下,它应该有效(您仍然应该了解这两个选项之间的差异,以便更好地处理您的数据)。


更完整的答案

基本上是什么正常化其作用是将字符串中的所有 unicode 转换为其规范的等效形式(或兼容形式),以便我们有等效的比较参考(现在理解这一点已经需要了解一些概念)。

关键是,unicode 不仅建立了数字(用 U+ 表示的代码点)与其字形之间的映射,而且还建立了这些点之间如何相互作用的一些规则。

例如,让我们采用字形á.

对于这个字符,我们并没有只有一个 unicode。我们实际上可以像这样表示它U+00E1或者喜欢U+0061U+0301这是unicodesa and ´.

是的! Unicode 的定义方式使您可以组合字符和变音符号,并通过一个接一个地排序来表示它们的联合。

事实上,你可以玩一下组合变音符号 https://en.wikipedia.org/wiki/Combining_Diacritical_Marks在 Unicode 中使用在线对话者 https://r12a.github.io/apps/conversion/:

Unicode 将这些可以组合成变音符号的字符类型定义为预制字符 https://en.wikipedia.org/wiki/Precomposed_character通过使用一个聪明而简单的想法:非预先组合的字符具有所谓的 0(零)结合类;可以组合的点接收正组合类(例如,´有类 230),用于断言最终字形应如何表示。

这很酷,但最终产生了一个解释该功能的问题正常化我们从一开始就一直在讨论:如果我们读取两个字符串,其中一个是 unicodeU+0061U+0301和其他与U+00E1 (both á),它们应该被认为是等价的!事实上,它是用不同方式表示的相同字形。

这正是normalize是在做。 Unicode 为每个字符定义了一个规范形式,这样,在规范化时,最终结果应该是这样的:如果我们有两个具有相同字形的不同代码点的字符串,我们仍然可以看到两者是相等的。

好吧,我们如何规范化代码点基本上有两种主要可能性:要么构成将不同的 unicode 转换为一个(在我们的示例中,这将转换为U+0061U+0301 into U+00E1)或者我们可以分解(这将是相反的,转变U+00E1 into U+0061U+0301).

在这里你可以更清楚地看到它:

NF 表示规范等价物 https://en.wikipedia.org/wiki/Unicode_equivalence。 NFC表示检索规范复合字符(联合); NFD则相反,分解字符。

您可以使用此信息在 BigQuery 中进行操作:

WITH data AS(
  SELECT 'Amélie' AS text
)

SELECT
  text,
  TO_CODE_POINTS(NORMALIZE(text, NFC)) nfc_result,
  TO_CODE_POINTS(NORMALIZE(text, NFD)) nfd_result
FROM data

哪些结果:

注意nfd列多了一个代码点。现在你已经知道那是什么了:´与分离e.

如果您阅读 BigQuery 的文档正常化,您会看到它还支持 NFKC 和 NFKD 类型。这种类型(带字母K) 不是通过规范等价而是通过“兼容性”进行规范化,也就是说,它还将一些字符分解为其组成字母,而不仅仅是变音符号:

这封信(与 ffi 不同。这种类型的字符称为ligature https://en.wikipedia.org/wiki/Typographic_ligature) 也被构成它的字母分解(因此等价性丢失,因为对于某些应用程序 ffi 可能与 ffi 不同,因此名称兼容形式)。

现在我们知道如何将字符分解为主要字形及其变音符号,我们可以使用regex仅匹配要从字符串中删除的它们(这是通过表达式完成的\pM仅匹配变音符号):

WITH data AS(
  SELECT 'café' AS text
)

SELECT
  REGEXP_REPLACE(NORMALIZE(text, NFD), r'\pM', '') nfd_result
FROM data

这几乎就是(希望如此)的全部内容了正常化函数以及如何使用它来删除变音符号。我找到的所有这些信息都感谢用户sigpwned https://stackoverflow.com/users/2103602/sigpwned和他的回答这个问题 https://stackoverflow.com/questions/43145902/bigquery-convert-accented-characters-to-their-plain-ascii-equivalents。当我尝试过但效果不太好时,我决定研究这些方法背后的一些理论,并想把它写下来:)。希望它对更多的人有用,就像对我有用一样。

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

如何在标准 SQL 中使用 Unicode 规范化删除变音符号(例如重音符号)? 的相关文章

随机推荐