回答
下面爲快速和簡單的選擇嘗試爲您提供:
#standardSQL
WITH lookups AS (
SELECT
'ç,æ,œ,á,é,í,ó,ú,à,è,ì,ò,ù,ä,ë,ï,ö,ü,ÿ,â,ê,î,ô,û,å,ø,Ø,Å,Á,À,Â,Ä,È,É,Ê,Ë,Í,Î,Ï,Ì,Ò,Ó,Ô,Ö,Ú,Ù,Û,Ü,Ÿ,Ç,Æ,Œ,ñ' AS accents,
'c,ae,oe,a,e,i,o,u,a,e,i,o,u,a,e,i,o,u,y,a,e,i,o,u,a,o,O,A,A,A,A,A,E,E,E,E,I,I,I,I,O,O,O,O,U,U,U,U,Y,C,AE,OE,n' AS latins
),
pairs AS (
SELECT accent, latin FROM lookups,
UNNEST(SPLIT(accents)) AS accent WITH OFFSET AS p1,
UNNEST(SPLIT(latins)) AS latin WITH OFFSET AS p2
WHERE p1 = p2
),
yourTableWithWords AS (
SELECT word FROM UNNEST(
SPLIT('brasília,ångström,aperçu,barège, beau idéal, belle époque, béguin, bête noire, bêtise, Bichon Frisé, blasé, blessèd, bobèche, boîte, bombé, Bön, Boötes, boutonnière, bric-à-brac, Brontë Beyoncé,El Niño')
) AS word
)
SELECT
word AS word_with_accent,
(SELECT STRING_AGG(IFNULL(latin, char), '')
FROM UNNEST(SPLIT(word, '')) char
LEFT JOIN pairs
ON char = accent) AS word_without_accent
FROM yourTableWithWords
輸出是
word_with_accent word_without_accent
blessèd blessed
El Niño El Nino
belle époque belle epoque
boîte boite
Boötes Bootes
blasé blase
ångström angstrom
bobèche bobeche
barège barege
bric-à-brac bric-a-brac
bête noire bete noire
Bichon Frisé Bichon Frise
Brontë Beyoncé Bronte Beyonce
bêtise betise
beau idéal beau ideal
bombé bombe
brasília brasilia
boutonnière boutonniere
aperçu apercu
béguin beguin
Bön Bon
UPDATE
下面是如何收拾這個邏輯到SQL UDF - 如此accent2latin(word)
可以被稱爲做一個「神奇」的
#standardSQL
CREATE TEMP FUNCTION accent2latin(word STRING) AS
((
WITH lookups AS (
SELECT
'ç,æ,œ,á,é,í,ó,ú,à,è,ì,ò,ù,ä,ë,ï,ö,ü,ÿ,â,ê,î,ô,û,å,ø,Ø,Å,Á,À,Â,Ä,È,É,Ê,Ë,Í,Î,Ï,Ì,Ò,Ó,Ô,Ö,Ú,Ù,Û,Ü,Ÿ,Ç,Æ,Œ,ñ' AS accents,
'c,ae,oe,a,e,i,o,u,a,e,i,o,u,a,e,i,o,u,y,a,e,i,o,u,a,o,O,A,A,A,A,A,E,E,E,E,I,I,I,I,O,O,O,O,U,U,U,U,Y,C,AE,OE,n' AS latins
),
pairs AS (
SELECT accent, latin FROM lookups,
UNNEST(SPLIT(accents)) AS accent WITH OFFSET AS p1,
UNNEST(SPLIT(latins)) AS latin WITH OFFSET AS p2
WHERE p1 = p2
)
SELECT STRING_AGG(IFNULL(latin, char), '')
FROM UNNEST(SPLIT(word, '')) char
LEFT JOIN pairs
ON char = accent
));
WITH yourTableWithWords AS (
SELECT word FROM UNNEST(
SPLIT('brasília,ångström,aperçu,barège, beau idéal, belle époque, béguin, bête noire, bêtise, Bichon Frisé, blasé, blessèd, bobèche, boîte, bombé, Bön, Boötes, boutonnière, bric-à-brac, Brontë Beyoncé,El Niño')
) AS word
)
SELECT
word AS word_with_accent,
accent2latin(word) AS word_without_accent
FROM yourTableWithWords
它的工作!謝謝@Mikhail。這是一個非常好的解決方案! –
@FelipeCarlo - 當然。感謝您接受/投票。你可以進一步將它包裝成漂亮的SQL UDF,以便它更易於使用/「便攜」! –
@FelipeCarlo - 查看SQL更新UDF –
您可以撥打REPLACE()或REGEXP_REPLACE()。你可以在Remove accents/diacritics in a string in JavaScript找到一些正則表達式。
或者,您可以使用javascript UDF,但我預計它會變慢。
值得一提的是,什麼你問的是unicode text normalization簡化的情況。許多語言在其標準庫中都有此功能(例如,Java)。一種好的方法是插入已經規範化的文本BigQuery。如果這不起作用 - 例如,因爲您需要保留原始文本,並且擔心打到BigQuery's row size limit - 那麼您需要在查詢中進行標準化。
某些數據庫具有用於查詢的各種完整性的Unicode標準化(例如,PostgreSQL's unaccent method,PrestoDB's normalize method)的實現。不幸的是,BigQuery不是其中之一。在撰寫本文時,BigQuery中沒有文本規範化功能。這個答案的實現是一種「滾動你自己的未知」。當BigQuery發佈官方功能時,每個人都應該使用它!
假設你需要在你的查詢中進行規範化(並且Google還沒有提供這方面的功能),這些都是一些合理的選擇。
方法1:使用NORMALIZE
谷歌現在有拿出一個NORMALIZE
功能。 (感謝@WillianFuks在標註中的註釋!)現在,這是文本標準化的明顯選擇。例如:
SELECT REGEXP_REPLACE(NORMALIZE(text), r"\pM", '') FROM yourtable;
有是如何工作的,以及爲什麼需要在評論REGEXP_REPLACE
通話的簡要說明。
我已經留下了參考的其他方法。
方法2:使用REGEXP_REPLACE
和REPLACE
上的內容
我使用REGEXP_REPLACE
實現在傳統的SQL文本規範化的只有小寫的情況。 (在標準SQL的模擬是相當不言自明的。)我使用下面的查詢運行與1K左右的平均長度的文本字段一些測試在一個大表28M行:
SELECT id, text FROM
(SELECT
id,
CASE
WHEN REGEXP_CONTAINS(LOWER(text), r"[àáâäåæçèéêëìíîïòóôöøùúûüÿœ]") THEN
REGEXP_REPLACE(
REGEXP_REPLACE(
REGEXP_REPLACE(
REGEXP_REPLACE(
REGEXP_REPLACE(
REPLACE(REPLACE(REPLACE(REPLACE(LOWER(text), 'œ', 'ce'), 'ÿ', 'y'), 'ç', 'c'), 'æ', 'ae'),
r"[ùúûü]", 'u'),
r"[òóôöø]", 'o'),
r"[ìíîï]", 'i'),
r"[èéêë]", 'e'),
r"[àáâäå]", 'a')
ELSE
LOWER(text)
END AS text
FROM
yourtable ORDER BY id LIMIT 10);
與:
WITH lookups AS (
SELECT
'ç,æ,œ,á,é,í,ó,ú,à,è,ì,ò,ù,ä,ë,ï,ö,ü,ÿ,â,ê,î,ô,û,å,ø,ñ' AS accents,
'c,ae,oe,a,e,i,o,u,a,e,i,o,u,a,e,i,o,u,y,a,e,i,o,u,a,o,n' AS latins
),
pairs AS (
SELECT accent, latin FROM lookups,
UNNEST(SPLIT(accents)) AS accent WITH OFFSET AS p1,
UNNEST(SPLIT(latins)) AS latin WITH OFFSET AS p2
WHERE p1 = p2
)
SELECT foo FROM (
SELECT
id,
(SELECT STRING_AGG(IFNULL(latin, char), '') AS foo FROM UNNEST(SPLIT(LOWER(text), '')) char LEFT JOIN pairs ON char=accent) AS foo
FROM
yourtable ORDER BY id LIMIT 10);
平均來說,REGEXP_REPLACE
實施約2.9s跑;基於陣列的實現在大約12.5s內運行。
方法3:在搜索模式
什麼把我帶到了這個問題,我是一個搜索的使用情況下使用REGEXP_REPLACE
。對於這個用例,我可以規範化我的語料庫文本,使其看起來更像我的查詢,或者我可以「非規範化」我的查詢,使它看起來更像我的文本。以上描述了第一種方法的實現。這描述了第二個的實現。
當一個單詞搜索,可以使用REGEXP_MATCH
匹配功能,只使用以下方式更新查詢:
a -> [aàáaâäãåā]
e -> [eèéêëēėę]
i -> [iîïíīįì]
o -> [oôöòóøōõ]
u -> [uûüùúū]
y -> [yÿ]
s -> [sßśš]
l -> [lł]
z -> [zžźż]
c -> [cçćč]
n -> [nñń]
æ -> (?:æ|ae)
œ -> (?:œ|ce)
所以查詢「你好」是這樣的,作爲一個正則表達式:
r"h[eèéêëēėę][lł][lł][oôöòóøōõ]"
將單詞轉換爲正則表達式應該在任何語言中都相當簡單。這不是針對發佈的問題的解決方案 - 「如何刪除BigQuery中的重音符號?」 - 而是相關用例的解決方案,這可能會將人們(如我!)帶到此頁面。
我想知道標準化方法如何解決這個問題。我嘗試使用新的[normalize](https://cloud.google.com/bigquery/docs/reference/standard-sql/functions-and-operators#normalize)函數,但它不起作用。你知道如何製作它嗎? –
當您使用新的'NORMALIZE'功能時,您是否簡單地調用'NORMALIZE'?默認情況下,該函數將從「變音符」字符中分解「字母」字符以創建重音字符的標準化序列表示,但不會刪除變音符號。如果要刪除變音符號,則需要執行另一步驟;像'REGEXP_REPLACE(s,r「[^ \ pL \ pN \ pP \ pS \ pZ]」,'')'或'REGEXP_REPLACE(s,r「[\ pM]」,'')'可能會做招。 (請參閱[這裏](https://github.com/google/re2/wiki/Syntax)瞭解這裏使用的unicode字符類。) – sigpwned
非常有趣的信息!感謝那! –
- 1. ColdFusion:將重音區域字符轉換爲純ASCII
- 2. 將非ASCII字符(變音符號,重音符號)轉換爲其最接近的ASCII等效字符(slug創建)
- 3. 如何重音符號的文本轉換爲純文本[R
- 4. 擴展ASCII字符,如歐元符號轉換爲它的Unicode等效
- 5. 將Unicode字符轉換爲等效的ASCII字符
- 6. 將等效的unicode字符串轉換爲Java中的ASCII碼?
- 7. 轉換的ASCII字符的字符串轉換成他們的ASCII碼,並將其分配給一個變量
- 8. 如何將unicode字符轉換爲c#中的轉義ascii等效字符#
- 9. 將重音字符轉換爲ASCII字符
- 10. 將法語重音字符轉換或轉換爲基本ASCII字符
- 11. 轉換的數字的字符串到他們hex等值
- 12. 替換他們的口音
- 13. 如何通過他們的HTML表示,以取代重音符號
- 14. 如何將重音字符轉換爲Java中的HTML符號?
- 15. 將字符實體轉換爲它們的Unicode等效
- 16. 轉換HTML轉義字符串將純Unicode/ASCII
- 17. 刪除重音符號 - 用無重音符號的字母替換重音符號str_replace
- 18. java - request.getParameter自動將編碼的HTML轉換爲其等效的ASCII字符
- 19. JDBC-ODBC橋查詢訪問時,他們已重音符號
- 20. 如何將Selenium腳本轉換爲等效的純Javascript?
- 21. c#:如何將一個Unicode字符轉換爲它的ASCII等效
- 22. 重定向與ASCII字符的URL在他們
- 23. 用C#中的ASCII等效替換特殊字符Silverlight
- 24. java.text.Normalizer等效於Java ME(用於替換重音字符)
- 25. java.lang.NumberFormatException:轉換字符串以ASCII
- 26. 轉換鍵碼爲重點的等效字符串
- 27. 重音符號
- 28. 在純LUA中將UTF-8字符串轉換爲ASCII
- 29. 轉換Unicode字符,以他們的性格
- 30. Obj中符號&符號(&)的ASCII等價性C
剛剛宣佈StandardSQL:[normalize](http://cloud.google.com/bigquery/docs/reference/standard-sql/functions-and-operators#normalize) –