Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Помогите составить регулярное выражение / 25 сообщений из 27, страница 1 из 2
02.03.2017, 16:13
    #39413225
Alibek B
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить регулярное выражение
Мне нужно распарсить адресную строку на составляющие.
Проблема в том, что строка шаблона получается сложная и мне не хватает 9 ссылок (\1...\9) при использовании regexp_replace. А при использовании regexp_substr возвращается все выражение соответствующее шаблону, хотя мне нужно взять из этого выражения только часть.
Адресная строка имеет вид: НП; Улица, Дом/Блок, Место; Примечания
Улица — обязательное и всегда должно присутствовать, все остальные части могут отсутствовать (и в этом случае не указываются также соседствующие разделители).
НП — населенный пункт, может содержать буквы, цифры, пробел и дефис.
Улица — улица, может содержать буквы, цифры, пробел и дефис.
Дом — номер дома, содержит только числа (цифровые символы).
Блок — дополнение к номеру (номер корпуса, блока, литера), может содержать буквы и цифры.
Место — может содержать префикс, буквы и цифры, список возможных префиксов ограничен ("кв. ", "офис ", "каб. ");
Примечание — произвольный текст.

Теоретически текстовые данные могут быть в Unicode, поэтому задавать в шаблоне "[- 0-9A-Za-zА-Яа-я]" видимо не всегда правильно, но почему-то у меня не работает класс [:alphanum:] (Oracle 10g).

Подскажите, можно ли составить для regexp_substr шаблон таким образом, чтобы он вернул только искомую часть?
Например такое выражение:
Код: plaintext
regexp_substr(VALUE, '^(([- 0-9A-ZА-Я]+); )?', 1, 1, 'i')
возвращает мне наименование населенного пункта с последующим разделителем (например "Москва; ").
Такое выражение:
Код: plaintext
regexp_replace(VALUE, '^(([- /0-9A-ZА-Я]+); )?.*$', '\2')
возвращает наименование в том виде, в котором нужно, но с таким подходом мне не хватает номеров ссылок.
________________________
Мы смотрим с оптимизмом...
...в оптический прицел.
...
Рейтинг: 0 / 0
02.03.2017, 16:49
    #39413268
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить регулярное выражение
Alibek B.можно ли составить для regexp_substr шаблон таким образом, чтобы он вернул только искомую часть?Переходить на 11g.


Alibek B.Мы смотрим с оптимизмом...
...в оптический прицел.Ради бога, убери эту херню.
...
Рейтинг: 0 / 0
02.03.2017, 17:03
    #39413280
Alibek B
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить регулярное выражение
Оказалось, что квадратные скобки нужно удваивать.
Так классы работают:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
select ...
, VALUE as ADDRESS
, regexp_replace(VALUE, '^(([[:alnum:] -]+); )?.*$', '\2') as ADR_CITY
, regexp_replace(VALUE, '^([[:alnum:] -]+; )?([[:alnum:] -]+).*$', '\2') as ADR_STREET
, regexp_replace(VALUE, '^([[:alnum:] -]+; )?([[:alnum:] -]+)(, ([0-9]+)(/[[:alnum:]]+)?)?.*$', '\4') as ADR_HOME
, regexp_replace(VALUE, '^([[:alnum:] -]+; )?([[:alnum:] -]+)(, ([0-9]+)(/([[:alnum:]]+))?)?.*$', '\6') as ADR_BLOCK
, regexp_replace(VALUE, '^([[:alnum:] -]+; )?([[:alnum:] -]+)(, ([0-9]+)(/([[:alnum:]]+))?)?(, ((кв\.|каб\.|офис) ?[[:alnum:]]+))?.*$', '\8') as ADR_PLACE
, regexp_replace(VALUE, '^([[:alnum:] -]+; )?([[:alnum:] -]+)(, ([0-9]+)(/([[:alnum:]]+))?)?(, (кв\.|каб\.|офис) ?([[:alnum:]]+))?.*$', '\9') as ADR_ROOM
, regexp_replace(VALUE, '^([[:alnum:] -]+; )?[[:alnum:] -]+(, [0-9]+(/[[:alnum:]]+)?)?(, (кв\.|каб\.|офис) ?[[:alnum:]]+)?(; +(.*))?.*$', '\7') as ADR_NOTES
...
Но шаблоны очень громоздкие, хотя и удалось уместиться в 9 ссылок.
Не посоветуете, как их можно оптимизировать?
...
Рейтинг: 0 / 0
02.03.2017, 18:01
    #39413316
блох
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить регулярное выражение
ElicРади бога, убери эту херню.

Ради какого?
...
Рейтинг: 0 / 0
02.03.2017, 18:29
    #39413324
--Eugene--
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить регулярное выражение
ElicAlibek B.Мы смотрим с оптимизмом...
...в оптический прицел.Ради бога, убери эту херню.+1
...
Рейтинг: 0 / 0
02.03.2017, 18:53
    #39413330
avas
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить регулярное выражение
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
select VALUE as ADDRESS
, regexp_replace(VALUE, '^(([[:alnum:] -]+); )?.*$', '\2') as ADR_CITY
, regexp_replace(VALUE, '^([[:alnum:] -]+; )?([[:alnum:] -]+).*$', '\2') as ADR_STREET
, regexp_replace(VALUE, '^([[:alnum:] -]+; )?([[:alnum:] -]+)(, ([0-9]+)(/[[:alnum:]]+)?)?.*$', '\4') as ADR_HOME
, regexp_replace(VALUE, '^([[:alnum:] -]+; )?([[:alnum:] -]+)(, ([0-9]+)(/([[:alnum:]]+))?)?.*$', '\6') as ADR_BLOCK
, regexp_replace(VALUE, '^([[:alnum:] -]+; )?([[:alnum:] -]+)(, ([0-9]+)(/([[:alnum:]]+))?)?(, ((кв\.|каб\.|офис) ?[[:alnum:]]+))?.*$', '\8') as ADR_PLACE
, regexp_replace(VALUE, '^([[:alnum:] -]+; )?([[:alnum:] -]+)(, ([0-9]+)(/([[:alnum:]]+))?)?(, (кв\.|каб\.|офис) ?([[:alnum:]]+))?.*$', '\9') as ADR_ROOM
, regexp_replace(VALUE, '^([[:alnum:] -]+; )?[[:alnum:] -]+(, [0-9]+(/[[:alnum:]]+)?)?(, (кв\.|каб\.|офис) ?[[:alnum:]]+)?(; +(.*))?.*$', '\7') as ADR_NOTES
FROM
(
SELECT '107-0052 Tokyo-to, Minato-ku, Akasaka, 4 Chome-3-2' AS value FROM dual
);



ни очень оно как-то работает
...
Рейтинг: 0 / 0
02.03.2017, 20:12
    #39413354
ln123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить регулярное выражение
Alibek B.,

Можно воспользоваться фактом что улица есть всегда тогда шаблоны станут чуть проще например
для дома, блока и места можно сделать вот так

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
select VALUE as ADDRESS
, regexp_replace(VALUE, '^(([[:alnum:] -]+); )?.*$', '\2') as ADR_CITY
, regexp_replace(VALUE, '^([[:alnum:] -]+; )?([[:alnum:] -]+).*$', '\2') as ADR_STREET
, regexp_replace(VALUE, '^([[:alnum:] ;-]+)(, ([0-9]+)(/[[:alnum:]]+)?)?.*$', '\3') as ADR_HOME
, regexp_replace(VALUE, '^([[:alnum:] ;-]+)(, ([0-9]+)(/([[:alnum:]]+))?)?.*$', '\5') as ADR_BLOCK
FROM
(
SELECT 'НП; Улица, 13/Блок, кв. 12; Примечания' AS value FROM dual
);



для места можно понадеяться на специфичность шаблона
и сделать например так:
Код: plsql
1.
regexp_replace(VALUE, '^.+((кв\.|каб\.|офис) ?[[:alnum:]]+).*$', '\1') as ADR_PLACE



а вообще возможно лучше сделать trim(';' from trim(',' from regexp_substr(...)))
...
Рейтинг: 0 / 0
02.03.2017, 20:31
    #39413359
Alibek B
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить регулярное выражение
avasни очень оно как-то работает
И не должно — данные не соответствуют шаблону.

ln123а вообще возможно лучше сделать trim(';' from trim(',' from regexp_substr(...)))
Действительно, попробую таким образом.
...
Рейтинг: 0 / 0
02.03.2017, 21:21
    #39413375
Jafa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить регулярное выражение
это так, альтернатива для размышления
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
WITH tbl AS
(
    SELECT '107-0052 Tokyo-to, Minato-ku, Akasaka, 4 Chome-3-2' AS ADDR FROM DUAL
)
SELECT 
    EXTRACTVALUE(XMLType('<xb><rw>'||REPLACE(ADDR, ',', '</rw><rw>')||'</rw></xb>').EXTRACT('//rw[position()=1]'), 'rw') AS city,
    EXTRACTVALUE(XMLType('<xb><rw>'||REPLACE(ADDR, ',', '</rw><rw>')||'</rw></xb>').EXTRACT('//rw[position()=3]'), 'rw') AS street,
    EXTRACTVALUE(XMLType('<xb><rw>'||REPLACE(ADDR, ',', '</rw><rw>')||'</rw></xb>').EXTRACT('//rw[position()=4]'), 'rw') AS house
FROM tbl;
...
Рейтинг: 0 / 0
02.03.2017, 23:10
    #39413414
Alibek B
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить регулярное выражение
У меня ведь позиции полей не фиксированные, иначе я бы обычным INSTR обошелся.
Но мысль понял, подумаю в этом направлении.
...
Рейтинг: 0 / 0
28.03.2017, 21:01
    #39428772
dvksqlru
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить регулярное выражение
Здравствуйте, есть список вида [0-9]{1}.[0-9]{1,2}.[0-9]{1,2}.[0-9]{1,2}.[0-9]{1,2}.
например: 1.2.13.2. или 1.23.2.1.11.

хотелось бы значения вида .[0-9]{1}. представить в виде .0[0-9]{1}. ,
например .1. как .01. или .3. как .03.

Подготовлен код вида
Код: plsql
1.
select regexp_replace(value, '\.[0-9]{1}\.', 'Что подставить сюда?') from dual


Например:
Код: plsql
1.
select regexp_replace('1.4.10.1.', '\.[0-9]{1}\.', 'Что подставить сюда?') from dual



Который ищет необходимые вхождения, однако что подставить на замену ума не приложу. Может кто подсказать?
...
Рейтинг: 0 / 0
28.03.2017, 21:38
    #39428786
Alibek B
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить регулярное выражение
Заключить искомый шаблон в скобки, по краям добавить ".*", третьим аргументом указать \1.
...
Рейтинг: 0 / 0
28.03.2017, 21:53
    #39428793
dvksqlru
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить регулярное выражение
Можно пример?
...
Рейтинг: 0 / 0
29.03.2017, 08:46
    #39428921
Alibek B
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить регулярное выражение
Код: plsql
1.
select regexp_replace('1.4.10.1.', '^.*(\.[0-9]{1}\.).*$', '\1') from dual
...
Рейтинг: 0 / 0
29.03.2017, 08:47
    #39428924
Alibek B
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить регулярное выражение
Хотя нет.
Код: plsql
1.
select regexp_replace('1.4.10.1.', '\.([0-9]{1})\.', '.0\1.') from dual
...
Рейтинг: 0 / 0
29.03.2017, 09:46
    #39428951
dvksqlru
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить регулярное выражение
Alibek B.Хотя нет.
Код: plsql
1.
select regexp_replace('1.4.10.1.', '\.([0-9]{1})\.', '.0\1.') from dual



Да, так почти работает, но почему-то в этом случае не форматирует предпоследний уровень:
Код: plsql
1.
select regexp_replace('1.4.10.3.7.8.', '\.([0-9]{1})\.', '.0\1.') from dual



Код: plsql
1.
1.04.10.03.7.08.
...
Рейтинг: 0 / 0
29.03.2017, 10:10
    #39428975
Alibek B
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить регулярное выражение
Не предпоследний, а через один.
Перед семеркой находится образец ".3." и следующий поиск продолжается далее, с подстроки "7.8.".
Поэтому первая цифра с шаблоном не совпадает (нет предшествующей точки) и находится следующая цифра.
Наверное с помощью одного регулярного выражения это не решить.
Можно сделать так:
Код: plaintext
select regexp_replace(regexp_replace('1.4.10.3.7.8.', '([0-9]+)', '00\1'), '0*([0-9]{2})', '\1') as re from dual
...
Рейтинг: 0 / 0
29.03.2017, 10:53
    #39429017
dvksqlru
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить регулярное выражение
Alibek B.,

Спасибо!
...
Рейтинг: 0 / 0
01.04.2017, 22:57
    #39431423
Alibek B
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить регулярное выражение
Подскажите, как решить такой вопрос?
Из строки нужно получить номер этажа.
Использую такое выражение:
Код: plsql
1.
regexp_replace(VALUE, '^.*((э\. *|эт\. *|этаж +)([[:digit:]]+)).*$', '\3')


Выражение отлично работает, если в строке указан этаж. Но если он отсутствует, такой шаблон не работает.
Если указываю так:
Код: plsql
1.
regexp_replace(VALUE, '^.*((э\. *|эт\. *|этаж +)([[:digit:]]+))?.*$', '\3')


то почему-то этаж вообще не находится, ни в одной строке.
...
Рейтинг: 0 / 0
02.04.2017, 02:19
    #39431451
ma1tus
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить регулярное выражение
Alibek B.Выражение отлично работает, если в строке указан этаж. Но если он отсутствует, такой шаблон не работает.
Код: plsql
1.
select regexp_replace(VALUE, '^.*((э\. *|эт\. *|этаж +)([[:digit:]]+)).*$|[^\1]', '\3') from dual

а так - работает?
...
Рейтинг: 0 / 0
02.04.2017, 04:29
    #39431455
ma1tus
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить регулярное выражение
ma1tusа так - работает?
нет, чушь. сорри.
...
Рейтинг: 0 / 0
02.04.2017, 08:00
    #39431465
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить регулярное выражение
Alibek B.
Код: plsql
1.
regexp_replace(VALUE, '^.*((э\. *|эт\. *|этаж +)([[:digit:]]+))?.*$', '\3')

Чересчур жадно.
...
Рейтинг: 0 / 0
03.04.2017, 11:16
    #39431898
Alibek B
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить регулярное выражение
ElicЧересчур жадно.
Непонятно.
Я разумеется пробовал указать ^.*?, не помогло.
Регулярное выражение составить не смог и в конечном итоге сделал case when regexp_like() then regexp_replace() end.
...
Рейтинг: 0 / 0
03.04.2017, 12:30
    #39431944
Maxim Demenko
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить регулярное выражение
Alibek B.ElicЧересчур жадно.
Непонятно.
Я разумеется пробовал указать ^.*?, не помогло.
Регулярное выражение составить не смог и в конечном итоге сделал case when regexp_like() then regexp_replace() end.
Elic подсказал конечно же правильно, то что не помогло - это ваши локальные грабли (скорее всего с NLS настройками на клиенте), у меня в plsql developer тоже выдает все замены как null - ковыряться на работе не могу, ибо все настройки заблокированы, но в sqlplus :
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
SQL> with t as (
  2  select 'этаж 15, Сидоровы' val from dual union all
  3  select 'э. 15 , Ивановы' val from dual union all
  4  select ' 15 , Ивановы' val from dual union all
  5  select 'эт. 15  , Петровы' val from dual )
  6  select
  7  val
  8  , regexp_replace(VAL, '^.*?((э\. *|эт\. *|этаж +)(\d+))?.*$', '\3') etage
  9  from t;

VAL                            ETAGE
------------------------------ --------------------
этаж 15, Сидоровы  15
э. 15 , Ивановы        15
 15 , Ивановы
эт. 15  , Петровы     15



Regards

Maxim
...
Рейтинг: 0 / 0
04.04.2017, 15:45
    #39433005
Vladimir Filin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить регулярное выражение
Alibek B. , может что-то пригодится из работающего кода на 11R2. Привожу куски кода, содержащего наиболее сложные regexp-ы,
т.к. ты запрашиваешь именно это.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
CREATE OR REPLACE PACKAGE addr_search AS
 lexem_delimiter_    CONSTANT VARCHAR2(1) := ' '; --разделитель частей адреса (лексем) в поисковой строке пользователя
 lexem_s3_           CONSTANT PLS_INTEGER := -3; --кандидат для позиционного поиска
 lexem_jast_digit_   CONSTANT PLS_INTEGER := -2; --лексема является просто цифрой/цифрами
 lexem_default_      CONSTANT PLS_INTEGER := -1; --текстовая лексема, не похожа на д.к.с.
 lexem_dks_prefix_   CONSTANT PLS_INTEGER := 0; --лексема похожа на префикс д.к.с., с паразитным пробелом справа
 lexem_dom_          CONSTANT PLS_INTEGER := 1; --лексема похожа на дом
 lexem_korp_         CONSTANT PLS_INTEGER := 2; --лексема похожа на корпус
 lexem_str_          CONSTANT PLS_INTEGER := 3; --лексема похожа на строение
 lexem_s3complex_    CONSTANT PLS_INTEGER := 9; --комплексный тип лексемы в позиционном поиске
....
END addr_search;
/

CREATE OR REPLACE PACKAGE BODY addr_search AS
.....

--Стартовая обработка поисковой строки пользователя перед smart / naive парсингом и определения релевантности
 FUNCTION pre_launch(user_str IN VARCHAR2)
  RETURN VARCHAR2 IS
  user_str_   VARCHAR2(2048 CHAR); --входная строка псле чистки
 BEGIN
  user_str_ :=
   TRANSLATE(TRIM(user_str), 'eyuopagkxcbnmETOPAHKXCBMЁё*?@#№$^=_|[]{}~,;:+<>"''`', 'еуиорадкхсьпмЕТОРАНКХСВМЕе%_'); --удаление транслитерации и мусора,*? -> %_
  user_str_ := REGEXP_REPLACE(user_str_, '!{2,}', '!', 1, 0, 'i'); --превращение повторяющихся ! в один !
  WHILE REGEXP_LIKE(' ' || user_str_ || ' ', '[[:space:]][%_!]*![%_!]*[[:space:]]', 'i') LOOP --удаление мусорных комбинаций из !%_
   user_str_ := REGEXP_REPLACE(' ' || user_str_ || ' ', '[[:space:]][%_!]*![%_!]*[[:space:]]', ' ', 1, 0, 'i');
  END LOOP;
  user_str_ := REGEXP_REPLACE(user_str_, '%{2,}', '%', 1, 0, 'i'); --превращение повторяющихся ! в один !
  user_str_ := REGEXP_REPLACE(user_str_, '[[:space:]]{2,}', ' ', 1, 0, 'i'); --удаление повторяющихся пробелов
  RETURN (TRIM(user_str_));
 END pre_launch;
....

--Распознавание номеров домов, корпусов, строений
 PROCEDURE dks_parser(lexem IN OUT VARCHAR2, lexem_typ OUT NUMBER, cleaned_lexem OUT VARCHAR2, not_lexem OUT BOOLEAN, empty_lexem OUT BOOLEAN) IS
 BEGIN
  lexem_typ := NULL;
  empty_lexem := FALSE;
  not_lexem := REGEXP_LIKE(lexem, '.!|!.', 'i'); --проверка на принудительное мсключение лексемы(NOT)
  lexem := REPLACE(lexem, '!', NULL); --чистка !
  cleaned_lexem := lexem;

  IF lexem IS NOT NULL THEN
   lexem_typ := lexem_default_; --содержит буквы без цифр
   IF REGEXP_LIKE(lexem,
      '^(д(ом)*[-/\%_]в(л([ао]д(ен([ие]е)*)*)*)*[%_]*|д(ом[оа])*[%_]*в(л([ао]д(ен([ие]е)*)*)*)*[%_]*|в(л([ао]д(ен([ие]е)*)*)*)*[%_]*|д(ом)*[%_]*)(([,:.]*[%_[:digit:]]+[[:print:]]*)|([,:.]+[%_[:alpha:]-]+))',
      'i') THEN
    --Идентификация Дома, владения, домовладения. Замена префикса на HHH
    cleaned_lexem :=
     REGEXP_REPLACE(lexem,
     '^(д[ом]*[-/\]в[лаодени]*|д[-омвладени/\]*|в[-лаодени/\]*)([~`!@#$^=|{}:"?+<>;'',.]*)([%_[:print:]]*)', '\3', 1, 0, 'i');
    lexem := 'HHH' || cleaned_lexem; --префикс HHH
    lexem_typ := lexem_dom_;

   ELSIF REGEXP_LIKE(lexem, '^(к([-/\о]*(([рп](ус)*)*|с))*)(([,:.]*[%_[:digit:]]+[[:print:]]*)|([,:.]+[%_[:alpha:]-]+))', 'i') THEN
    --Идентификация Корпуса. Замена префикса на KKK
    cleaned_lexem := REGEXP_REPLACE(lexem, '^(к[-орпус/\]*)([~`!@#$^=|{}:"?+<>;'',.]*)([%_[:print:]]*)', '\3', 1, 0, 'i');
    lexem := 'KKK' || cleaned_lexem; --префикс KKK
    lexem_typ := lexem_korp_;

   ELSIF REGEXP_LIKE(lexem, '^(с(([-/\]*т(р([оа]ен([ие])*)*)*)*|т[-/\]е)[%_]*)(([,:.]*[%_[:digit:]]+[[:print:]]*)|([,:.]+[%_[:alpha:]-]+))',
         'i') THEN
    --Идентификация Строения. Замена префикса на SSS
    cleaned_lexem := REGEXP_REPLACE(lexem, '^(с[-троаени/\]*)([~`!@#$^=|{}:"?+<>;'',.]*)([%_[:print:]]*)', '\3', 1, 0, 'i');
    lexem := 'SSS' || cleaned_lexem; --префикс SSS
    lexem_typ := lexem_str_;

   ELSIF REGEXP_LIKE(lexem,
         '^(д(ом)*[-/\%_]в(л([ао]д(ен([ие]е)*)*)*)*[%_]*|д(ом[оа])*[%_]*в(л([ао]д(ен([ие]е)*)*)*)*[%_]*|в(л([ао]д(ен([ие]е)*)*)*)*[%_]*|д(ом)*[%_]*)[[:punct:]]*$',
         'i') THEN
    --Идентификация одиночного префикса Дома, владения, домовладения
    IF not_lexem THEN
     lexem := 'HHH'; --префикс HHH
     lexem_typ := lexem_dom_;
     empty_lexem := TRUE;
    ELSE
     lexem_typ := lexem_dks_prefix_;
    END IF;

   ELSIF REGEXP_LIKE(lexem, '^(к([-/\о]*(([рп](ус)*)*|с))*[%_]*)[[:punct:]]*$', 'i') THEN
    --Идентификация одиночного префикса Корпуса
    IF not_lexem THEN
     lexem := 'KKK'; --префикс KKK
     lexem_typ := lexem_korp_;
     empty_lexem := TRUE;
    ELSE
     lexem_typ := lexem_dks_prefix_;
    END IF;

   ELSIF REGEXP_LIKE(lexem, '^(с(([-/\]*тр([оа]ен([ие])*)*)*|т[-/\]е)[%_]*)[[:punct:]]*$', 'i') THEN
    --Идентификация одиночного префикса Строения
    lexem_typ := lexem_dks_prefix_;
    IF not_lexem THEN
     lexem := 'SSS'; --префикс SSS
     lexem_typ := lexem_str_;
     empty_lexem := TRUE;
    ELSE
     lexem_typ := lexem_dks_prefix_;
    END IF;

   ELSIF REGEXP_LIKE(lexem, '^[%_]*[[:digit:]]+[%_]*$', 'i') THEN
    --Идентификация только цифр без чего-либо другого
    lexem_typ := lexem_jast_digit_;

   ELSIF REGEXP_LIKE(lexem, '([[:digit:]]+[-/\%_]+)|([[:digit:]]+[-/\%_]*[[:alpha:]]+)|([[:alpha:]]+[-/\%_]*[[:digit:]]+)|(^[%_]*-[%_]*$)', 'i') THEN
    --Идентификация кандидата для номера дома/корпуса/строения для позиционного распознавания
    lexem_typ := lexem_s3_;
   END IF;
  END IF;
 END dks_parser;
....
END addr_search;
/



Для Питера нужно дописать распознавание Литер домов.
Что бы мозк не свернуть в сингулярность на regexp-ах использую RegexBuddy -- мне нравится.
Для адекватного тестирования парсинга адресов (Москвы) натаскал когда-то из БД БТИ "хорошие" и "очень плохие" адреса, держи:
4-я 8 Марта ул., д.3 стр.1
4-я 8 Марта ул., д.3 стр.1
4-я 8 Марта ул., д.4 кор.1
4-я 8 Марта ул., д.6А стр.1
2-я Песчаная ул., д.2 кор.2
2-я Песчаная ул., д.2 кор.1
1905 Года ул., д.25
1905 Года ул., д.27 стр.5
1812 Года ул., д.15 стр.8
1812 Года ул., д.15
800-летия Москвы ул., д.8 стр.1
800-летия Москвы ул., д.8
9 мая
9 Мая ул., д.9
9 Мая ул., д.10
Красного Маяка ул., д.9
Маяковского пер., д.11-13/16 стр.9
Маяковского ул., д.9
N 5500
N 5500 пр., д.Б/Н стр.1
N 5500 пр., д.5А стр.5
Южн.промзона, N 4922 пр., стр.10
Проектируемый N 4294 пр., д.2 стр.4
Панфилова (г.Зеленоград)
Панфилова (г.Зеленоград) ул., д.13 стр.1
Панфилова (г.Зеленоград) ул., д.15А
Панфилова ул., д.2 кор.1
Панфилова ул., д.2 кор.2
Октябрьская ж.д., Московское, 646 км прочие, стр.1
Октябрьская ЖД, Москва-Санкт-Петербург, 10-й км прочие, стр.1
Новолужнецкий пр., Лужнецкая эстакада прочие, стр.1
МЖД, Рижское, 8-й км прочие, д.1
МЖД, Рижское, 8-й км прочие, д.1А стр.1
Волжский Бульвар 114А кварт., д.10 стр.1
Волжский Бульвар 114А кварт., д.Б/Н кор.9
Волжский бульвар 95 кварт., кор.2
Волжский бульвар 95 кварт., кор.3 стр.2
Бутово Северное 2 мкр., д.Н
Бутово Северное 3 мкр., кор.30
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Помогите составить регулярное выражение / 25 сообщений из 27, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]