scala — создайте регулярное выражение для RE2, чтобы игнорировать акценты

Я пытаюсь создать регулярное выражение, чтобы найти слово внутри таблицы в большом запросе, которое может содержать акценты. Ввод может иметь акценты или нет. Я пишу на scala, поэтому ввод можно преобразовать в scala или с помощью функций bigquery. Я думаю, хорошим решением может быть что-то вроде этого:

input: serie
word to find: Séries

Я могу преобразовать ввод в

r'(?i:s[éèe]r[íìi][éèe]s)'

но я думаю, что было бы лучше преобразовать столбец таблицы во что-то вроде:

r'(?i:s[ée]ries)'

Я не знаю, как решить вторую ситуацию или лучший способ ее решить. заранее спасибо


person Gastón Schabas    schedule 04.04.2017    source источник
comment
проверьте stackoverflow.com/a/43148949/5221944 - вы можете принять подход там - если это не поможет - уточните ваш вариант использования - я думаю, он недостаточно ясен   -  person Mikhail Berlyant    schedule 04.04.2017


Ответы (2)


Я пытаюсь создать регулярное выражение, чтобы найти слово внутри таблицы в большом запросе, которое может содержать акценты.

Поиграйте с примером ниже

поэтому ввод можно преобразовать в scala или с помощью функций bigquery

Он делает все в BigQuery Standard SQL.

#standardSQL
CREATE TEMP FUNCTION latin2accents(word STRING) AS
((
  WITH lookups AS (
    SELECT 
    'y,a,e,i,o,u,c,ç,n,æ,œ,á,é,í,ó,ú,à,è,ì,ò,ù,ä,ë,ï,ö,ü,ÿ,â,ê,î,ô,û,å,ø,Ø,Å,Á,À,Â,Ä,È,É,Ê,Ë,Í,Î,Ï,Ì,Ò,Ó,Ô,Ö,Ú,Ù,Û,Ü,Ÿ,Ç,Æ,Œ,ñ' AS accents,
    'y,a,e,i,o,u,c,c,n,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
  ), map AS (
    SELECT latin, CONCAT('[', STRING_AGG(accent, ''), ']') AS accents
    FROM pairs  
    GROUP BY latin
  )
  SELECT CONCAT('(?i:', STRING_AGG(IFNULL(accents, char), ''), ')')
  FROM UNNEST(SPLIT(word, '')) char
  LEFT JOIN map
  ON char = latin
));

WITH yourTable AS (
  SELECT 'Séries' AS word UNION ALL SELECT 'Series' UNION ALL
  SELECT 'brasília' UNION ALL SELECT 'Niño' UNION ALL SELECT 'aperçu' 
), inputs AS (
  SELECT 'series' AS input UNION ALL SELECT 'Brasilia' UNION ALL
  SELECT 'nino' UNION ALL SELECT 'apercu'
)
SELECT input, word AS found_word 
FROM yourTable CROSS JOIN inputs
WHERE REGEXP_CONTAINS(word,  latin2accents(input)) = TRUE
ORDER BY input, word

Вывод (я думаю, это то, что вы хотели)

input       found_word   
-----       ----------
Brasilia    brasília     
apercu      aperçu   
nino        Niño     
series      Series   
series      Séries   
person Mikhail Berlyant    schedule 05.04.2017

Используя Java Collator (см., например, этот ответ), можно было бы применить более простой подход:

scala> val c = java.text.Collator.getInstance()
c: java.text.Collator = java.text.RuleBasedCollator@289747d6
scala> c.setStrength(Collator.PRIMARY)
scala> c.equals("é","E")
res24: Boolean = true
scala> c.setStrength(Collator.SECONDARY)
scala> c.equals("é","E")
res26: Boolean = false

При этом учитывается ваш язык, так как правила для того, что составляет «базовый» (эквивалентный) символ, будут различаться в зависимости от языка.

person wwkudu    schedule 21.02.2019