# #sql #string #replace #google-bigquery
Вопрос:
Как и в названии. Лучшее, что приходит мне на ум, — это использование базовой REPLACE
функции , но она терпит неудачу с чем-то более сложным, чем просто I
, V
и X
т. Д.
Римские цифры в моих данных расположены в конце строки, поэтому, основываясь на известном фильме «Форсаж», мои данные выглядят так:
Фильм |
---|
Быстрый и Яростный Я |
Форсаж II |
Форсаж III |
Форсаж IV |
Форсаж V |
Форсаж VI |
Форсаж VII |
Комментарии:
1. Какое наибольшее число вы ожидаете? Серия замен может быть самой простой. Просто используйте правильный порядок: сначала попробуйте III, затем II и последнее I (и так далее)
Ответ №1:
Римские цифры в моих данных расположены в конце строки
Рассмотрите приведенный ниже подход (вместе с некоторыми фиктивными данными в дополнение к вашим)
create temp function deromanize (number STRING) returns STRING language js as ''' var number = number.toUpperCase(), validator = /^M*(?:D?C{0,3}|C[MD])(?:L?X{0,3}|X[CL])(?:V?I{0,3}|I[XV])$/, token = /[MDLV]|C[MD]?|X[CL]?|I[XV]?/g, key = {M:1000,CM:900,D:500,CD:400,C:100,XC:90,L:50,XL:40,X:10,IX:9,V:5,IV:4,I:1}, num = 0, m; if (!(number amp;amp; validator.test(number))) return false; while (m = token.exec(number)) num = key[m[0]]; return num; '''; with your_table as ( select 'Fast amp; Furious I' movie union all select 'Fast amp; Furious II' union all select 'Fast amp; Furious III' union all select 'Fast amp; Furious IV' union all select 'Fast amp; Furious V' union all select 'Fast amp; Furious VI' union all select 'Fast amp; Furious VII' union all select 'Fast amp; Furious XXXIX' union all select 'Fast amp; Furious LXXI' union all select 'Fast amp; Furious MDCCLXXIV' ) select movie, replace(movie, roman_number, deromanize(roman_number)) converted_title from your_table, unnest([struct(array_reverse(split(movie, ' '))[offset(0)] as roman_number)])
с выходом