Регулярные выражения в Oracle | |
---|---|
Pekpytep Автор Сообщений: 727 Откуда: Луганск Дата регистрации: 19.10.2010 |
Приветствую всех.
Есть экселевская таблица, загружаемая впоследствии в таблицу Oracle. Одно из полей содержит номер телефона, который может быть в виде +7 123 456 78 90, +7(123) 4567890, 8-123-456-78-90 и т.д. Пытаюсь причесать все номера к одному формату, содержащему исключительно цифры, используя regexp_replace(). Собственно, вопрос. Как удалить из строки пробелы, скобки, +, - и т.д. я понял, но только последовательно, цепочкой из нескольких regexp_replace(). Можно ли оставить в строке только цифры одним вызовом функции? Буду благодарен за готовый рецепт или хотя-бы подсказку. |
Re: Регулярные выражения в Oracle | |
---|---|
my Сообщений: 206 Дата регистрации: 09.06.2006 |
regexlib точка com
regexlib.com |
Re: Регулярные выражения в Oracle | |
---|---|
Pekpytep Автор Сообщений: 727 Откуда: Луганск Дата регистрации: 19.10.2010 |
Спасибо!
|
Re: Регулярные выражения в Oracle | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Проще надо быть
Есть ещё чуть менее наглядный, но точно такой же по сути вариант:
------------------ WBR, Igor Исправлено 2 раз(а). Последнее : Igor Korolyov, 14.12.16 11:53 |
Re: Регулярные выражения в Oracle | |
---|---|
Pekpytep Автор Сообщений: 727 Откуда: Луганск Дата регистрации: 19.10.2010 |
Давно не чувствовал себя так глупо...
|
Re: Регулярные выражения в Oracle | |
---|---|
Pekpytep Автор Сообщений: 727 Откуда: Луганск Дата регистрации: 19.10.2010 |
А как с помощью REGEXP_REPLACE оставить только цифры и десятичные разделители (.,) ?
|
Re: Регулярные выражения в Oracle | |
---|---|
Pekpytep Автор Сообщений: 727 Откуда: Луганск Дата регистрации: 19.10.2010 |
|
Re: Регулярные выражения в Oracle | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Да вроде просто
------------------ WBR, Igor Исправлено 1 раз(а). Последнее : Igor Korolyov, 16.05.17 18:39 |
Re: Регулярные выражения в Oracle | |
---|---|
Pekpytep Автор Сообщений: 727 Откуда: Луганск Дата регистрации: 19.10.2010 |
"Просто" только для тех, кто глубоко вник, а мне они что-то никак не даются. Никак не усвою группировку выражений, в чем разница выражений для regexp_replace между "заменить то на это" и "убрать все кроме этого".
|
Re: Регулярные выражения в Oracle | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Не, я тут под "просто" имел в виду что у тебя много лишних буковок Внутри квадратных скобок "особое значение" имеют лишь символы ^[]-
"Крышка" - только в первой позиции. Закрывающая квадратная скобка - КРОМЕ первой позиции. Открывающая квадратная скобка - в зависимости от следующего символа начинает POSIX character class, POSIX collation element или POSIX character equivalence class. Минус задаёт диапазон, кроме случая когда он первый в строке, последний в строке, или стоит после другого минуса (являясь в этом случае "просто символом минуса"). Твой пример включает ещё и * как символ, ну и по два раза добавляет и звезду и цифры в этот самый "набор для исключения". Если ты имел в виду шаблон "цифры, потом точка или запятая, потом снова цифры" то явно промахнулся. Да и REGEXP_REPLACE в этом виде не для того предназначен - он как раз ЗАМЕНЯЕТ найденный шаблон на нечто (если ничего в качестве замены не указано, как в этих примерах - удаляет его) а не БЕРЁТ то что подходит под шаблон выкидывая всё прочее. REGEXP_SUBSTR() может вынимать из строки то что подходит под шаблон. Например из строки 'В 2017 году ВВП страны увеличится на 1.15% и составит 1,234млрд, что на 0,22млрд больше чем в 2016 году'. Можно последовательно (используя соответствующие параметры функции) вынуть числа 2017 1.15 1,234 0,22 2016 Но при помощи исходной функции "фильтрации нечисел" мы получим ОДНУ строку вида 20171.151,234,0,222016 что, наверное, не совсем правильно будет Если ты хотел написать шаблон ищущий именно десятичное число (с одним из возможных разделителей) в строке, то нужен был бы шаблон примерно такого вида '[[:digit:]]+((\.|,)[[:digit:]]+)?'или то же самое, но короче за счёт применения \d вместо POSIX описания класса символов [:digit:], которые (такие "классы символов") должны быть всегда внутри квадратных скобок определяющих "набор символов". '\d+((\.|,)\d+)?'Если его рассматривать "по шагам": 1 \d+ ищем цифру встречающуюся 1 или более раз. Это "жадный" поиск - т.е. в поиск попадут ВСЕ цифры до тех пор пока не встретится "не цифра" 2 ( начало группы 3 ( начало вложенной группы 4 \.|, точка или запятая - точка экранируется, т.к. она не внутри "набора символов". Можно было тут вместо "группы с выбором" применить тот же "набор символов", написав вместо (\.|,) просто [.,] 5 ) конец вложенной группы - т.к. не задан квантификатор, то группа должна встретиться ровно 1 раз 6 \d+ ищем цифры встречающиеся 1 или более раз. Это "жадный" поиск - т.е. в поиск попадут ВСЕ цифры до тех пор пока не встретится "не цифра" 7 )? конец группы. Задан квантификатор "ноль или один" - т.е. ВСЯ эту группа (начиная с шага 2) является необязательной. У этого выражения есть изъян - он "не понимает" числа записанного БЕЗ целой части. Скажем .1234 Точнее, он для такого числа "потеряет" десятичный разделитель, вернув только его дробную часть т.е. 1234 в данном случае. Можно несколькими способами "исправить" такой недочёт. К примеру вот этим коротким, но немного "сложно понимаемым". '(\d*[.,])?\d+'Попробуй сам его "разобрать" по шагам, и понять почему он правильно находит и целые числа, и десятичные дроби, и дроби без целой части, и даже число в конце предложения (завершающееся точкой). ------------------ WBR, Igor |
Re: Регулярные выражения в Oracle | |
---|---|
Pekpytep Автор Сообщений: 727 Откуда: Луганск Дата регистрации: 19.10.2010 |
А эксперименты говорят о другом:
Цитата:
Цитата:
Цитата:Для меня такое поведение совершенно не очевидно и я не понимаю зависимость между шаблоном и результатом, почему в одном случае удаляет "все кроме", во втором - удаляет по шаблону, в третьем - не делает ничего. Целью было обработать десятичные числа при импорте из csv в БД, т.е. я хотел именно убрать из текстового поля ошибочно введенные символы кроме цифр и десятичных разделителей. |
Re: Регулярные выражения в Oracle | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
1 [ начинается набор символов 2 ^ это набор символов "всё кроме" 3 [:digit:] posix класс десятичных цифр 4 ,. просто два символа 5 ] завершается набор символов Итого - шаблон ищет все символы КРОМЕ десятичных цифр, точки и запятой. Шаблон используется в функции regexp_replace, которая ЗАМЕНЯЕТ найденные вхождения на свой 3-й параметр. т.к. 3-го параметра не указано, то заменяет на путоту - т.е. по сути вырезает их из строки. Что останется в строке в итоге? Как раз десятичные цифры, точки и запятые. Есть в этом проблема? Да, если пытаться применить напрямую to_number к этой "очищенной строке". Т.к. во-первых для to_number нужно задать ОДНОЗНАЧНЫЙ разделитель, во-вторых он не сможет правильно разобрать строку вида "123.456.789" - т.е. где как минимум несколько разделителей будет, не говоря уж о том что они будут разными.
Шаблон отличается тем, что это "позитивный" набор символов. Не "всё кроме", а именно "то что подходит". Подходят цифры, точка и запятая. Т.к. шаблон применён в regexp_replace без 3-го параметра, то эти самые найденные символы и заменяются на пустоту.
1 ^ символ не внутри квадратных скобок - он имеет специальное значение как "якорь начала строки". Т.е. такой шаблон будет проверять последующее выражение ТОЛЬКО в начальной позиции строки. 2 [:digit:] это НЕ posix класс символов (тот должен быть ВНУТРИ квадратных скобок), это ПРОСТО набор символов :digt - то что они повторяются роли не играет. 3 ,. это ПРОСТО два подряд идущих символа, которые должны находится строго после ОДНОГО символа подходящего под набор из шага 2 (т.к. набор идёт без квантификатора, что значит "ровно одно вхождение"). Итого: данный шаблон ищет набор из 3 символов :,. или d,. или i,. или g,. или t,. при том расположенный в начале строки. Т.к. шаблон применяется в regexp_replace без 3-го параметра, то в случае нахождения эти 3 символа будут удалены. т.е.
И во что должен превратится текст a1.b2.c3.d4e5 или a1,b2.c3,d4e5 или просто 123,456.78 ? ------------------ WBR, Igor Исправлено 1 раз(а). Последнее : Igor Korolyov, 19.05.17 12:11 |
Re: Регулярные выражения в Oracle | |
---|---|
Pekpytep Автор Сообщений: 727 Откуда: Луганск Дата регистрации: 19.10.2010 |
Видимо, в 1.2.3.45 1,2.3,45 123,456.78 Я не ставлю себе целью написать на plsql искусственный интеллект или парсер всех возможных сортов говна, которое могут прислать на загрузку. Если я ожидаю на вход десятичное число, то примитивные опечатки я могу обработать, но остальное отправлю в некорректные записи. |
Re: Регулярные выражения в Oracle | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Ну я имел в виду в какое ЧИСЛО это можно было бы превратить Ты же конвертируешь строки в даты, в числа - вот и вопрос возник, что с таким делать
------------------ WBR, Igor |
© 2000-2024 Fox Club  |