Wil*_*uks 7

简答

在理解了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
Run Code Online (Sandbox Code Playgroud)

结果:

Row   nfd_result    nfkd_result  
1     Aaiucao       Aaiucao  
Run Code Online (Sandbox Code Playgroud)

您可以使用"NFD"或"NFKD"选项,并且在大多数情况下,它应该可以工作(您仍然应该了解两个选项之间的差异以更好地处理您的数据).


更完整的答案

基本上规范化的做法是将字符串中的所有unicode转换为规范等价物(或兼容形式),以便我们有相同的比较参考(现在理解这已经需要了解一些概念).

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

例如,让我们拿字形á.

我们这个角色没有一个unicode.我们实际上可以代表它U+00E1或者喜欢U+0061U+0301哪个是unicodes for a´.

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

实际上,您可以使用在线对话来结合使用Unicode中的变音符号:

在此输入图像描述

Unicode定义了这些类型的字符,它们可以通过使用一个聪明而简单的想法将自身与变音符号组合预先组合的字符:未预先组合的字符具有所谓的0(零)组合类 ; 可以组合的点接收正组合类(例如,´具有类230),其用于断言应如何表示最终字形.

这很酷但最终会产生一个问题,这个问题解释了我们从一开始就讨论过的函数规范化:如果我们读取两个字符串,一个用unicode U+0061U+0301,另一个用U+00E1(两个á),它们应该被认为是等价的!实际上,它是以不同方式表示的相同字形.

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

那么,有基本上是我们如何能够标准化码点2种主要的可能性:要么组成不同的统一码到只有一个(在我们的例子中,这将被转化U+0061U+0301U+00E1),或者我们可以分解(这是周围的其他方式,转化U+00E1U+0061U+0301).

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

在此输入图像描述

NF表示规范等价物.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
Run Code Online (Sandbox Code Playgroud)

结果如下:

在此输入图像描述

请注意,该nfd列还有一个代码点.到现在为止,你已经知道那是什么了:´与...分开e.

如果你阅读BigQuery的文档进行规范化,你会发现它也支持NFKC和NFKD类型.这种类型(带字母K)不是通过规范等价来规范化,而是通过"兼容性"来规范化,也就是说,它将一些字符分解为其成分字母,而不仅仅是变音符号:

在此输入图像描述

字母?(与ffi不同.这种类型的字符称为连字)也由构成它的字母分解(因此,等价物丢失,因为对于某些应用,ffi可能与ffi不同,因此名称兼容形式).

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

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

SELECT
  REGEXP_REPLACE(NORMALIZE(text, NFD), r'\pM', '') nfd_result
FROM data
Run Code Online (Sandbox Code Playgroud)

而且几乎所有(希望)归一化函数以及它如何用于去除变音符号.我发现所有这些信息都归功于用户sigpwned以及他对这个问题的回答.当我尝试它并且它没有完成工作时,我决定研究这些方法背后的一些理论,并想把它写下来:).希望它对更多人有用,因为它绝对适合我.