Учитывая эту версию Oracle с целью преобразовать ее, чтобы ее можно было использовать в Databricks SQL:
WITH pattern AS (
SELECT
/*+ INLINE */
'^([A-Z][A-Z0-9])([A-Z]\d{3,4})([T])?([A-D])?([W]\d)?([A-RT-Z][A-Z0-9])?([V])?([Y])?([S][1-4])?$' AS pat_default,
'\1\2\3\4\7' rep_plain_lot
)
SELECT
t1.lot_number,
CASE
WHEN REGEXP_LIKE (t1.lot_number,(SELECT pat_default FROM rcod))
THEN
REGEXP_REPLACE (t1.lot_number,(SELECT pat_default FROM rcod),(SELECT rep_plain_lot FROM rcod))
ELSE
'no match'
END plain_lot_new
FROM table t1
Ожидаемый результат, например:
LOT_NUMBER | PLAIN_LOT
-----------+----------
A1X482 | A1X482
A1X482A | A1X482
Что бы я ни пробовал, это приводит к «нету совпадения». Я знаю, что мне нужно удвоить обратную косую черту, что я и сделал, но это ничего не изменило. Что я смог выяснить, так это то, что проблема, похоже, во втором шаблоне:
([A-Z]\d{3,4})
Я бы предположил в основном фигурные скобки. Мои исследования привели меня к:
([[:upper:]][[:digit:]]{3,4})
Но опять же, это всегда приводит к «нету соответствия». Я застрял.
нет, но спасибо за подсказку, я обновил свой вопрос круглыми скобками
Из документации Databricks regex_replace
Строка регулярного выражения должна быть регулярным выражением Java.
При использовании литералов используйте raw-литерал (префикс r), чтобы избежать предварительной обработки escape-символов.
Таким образом, вы сможете использовать что-то вроде (объединить первые 4 группы захвата в одну и упростить некоторые другие части):
SELECT t1.lot_number,
CASE
WHEN REGEXP_LIKE (
t1.lot_number,
r'^([A-Z][A-Z0-9][A-Z]\d{3,4}T?[A-D]?)(W\d)?([A-RT-Z][A-Z0-9])?(V)?Y?(S[1-4])?$'
)
THEN REGEXP_REPLACE (
t1.lot_number,
r'^([A-Z][A-Z0-9][A-Z]\d{3,4}T?[A-D]?)(W\d)?([A-RT-Z][A-Z0-9])?(V)?Y?(S[1-4])?$',
r'\1\4'
)
ELSE 'no match'
END AS plain_lot_new
FROM table_name t1
Мои исследования привели меня к:
([[:upper:]][[:digit:]]{3,4})
Java не поддерживает классы символов POSIX, и поскольку в документации указано, что «строка регулярного выражения должна быть регулярным выражением Java», это не будет работать (хотя это будет работать в Oracle, поскольку Oracle поддерживает классы символов POSIX).
Предполагая ввод ASCII, эквивалент регулярного выражения Oracle [A-Z]\d{3,4}
в качестве регулярного выражения Java будет одним из:
[A-Z]\d{3,4}
(действительно без изменений)\p{Upper}\p{Digit}{3,4}
\p{Upper}\p{Digit}\p{Digit}\p{Digit}\p{Digit}?
[A-Z]\d\d\d\d?
[A-Z][0-9]{3,4}
[A-Z][0-9][0-9][0-9][0-9]?
(Вероятно, есть и другие варианты.)
тестируем его: REGEXP_LIKE (t1.lot_number,r'^([A-Z][A-Z0-9])([A-Z]\d{3,4})([T])?([AD])? ([W]\d)?([A-RT-Z][A-Z0-9])?([V])?([Y])?([S][1-4]) ?$'); результат false__________, но проверка REGEXP_LIKE (t1.lot_number,r'^([A-Z][A-Z0-9])'); рестулс в истине. проблема во втором шаблоне
@Wondarar Тестирование в Oracle (все, что отличается, это удаление префикса r
из литералов) рабочий пример работает. Аналогично, тестируем его на regex101.com как работает регулярное выражение Java. Если это второй шаблон, вы можете попробовать заменить [A-Z]\d{3,4}
на [A-Z]\d\d\d\d?
или [A-Z][0-9][0-9][0-9][0-9]?
, но [A-Z]\d{3,4}
действителен как в Oracle, так и в Java, поэтому, если Databricks использует регулярные выражения Java, это не должно быть проблемой.
\p{Digit} — решение для моего случая, спасибо. Обратите внимание, я думаю, вы пропустили вторую обратную косую черту.
Попробуйте
([[:upper:]][[:digit:]]){3,4}