Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Скрипт разбора адресной строки  [new]
eggman
Member

Откуда:
Сообщений: 5
Здравствуйте.
Возникла задача разбора адресной строки в string в несколько полей: индекс, район, город, улица, дом, корпус, квартира.

Если кто сталкивался с подобной задачей, выложите скриптик, пожалуйста.
11 май 07, 13:04    [4125483]     Ответить | Цитировать Сообщить модератору
 Re: Скрипт разбора адресной строки  [new]
kill_zdm
Member

Откуда:
Сообщений: 1406
может ответ не поможет. я СУБД использую только как Хранилище инфы, а работу с ней реализую Средствами разработки, Delphi, напирмер. в паскале,как и в других языках программирования есть реализация работы со строками. Вот ты-быеще уточнил, как выглядит твой string
11 май 07, 13:09    [4125539]     Ответить | Цитировать Сообщить модератору
 Re: Скрипт разбора адресной строки  [new]
Бабичев Сергей
Member

Откуда:
Сообщений: 2498
Тынц - разбиение строк на лексемы, может чем поможет
11 май 07, 13:12    [4125578]     Ответить | Цитировать Сообщить модератору
 Re: Скрипт разбора адресной строки  [new]
SQL*Plus
Member

Откуда: Россия, Москва
Сообщений: 8132
eggman
Если кто сталкивался с подобной задачей, выложите скриптик, пожалуйста.
Когда свой скриптик отладите, не забудьте его в эту конференцию выложить.
Договорились?
11 май 07, 14:22    [4126208]     Ответить | Цитировать Сообщить модератору
 Re: Скрипт разбора адресной строки  [new]
eggman
Member

Откуда:
Сообщений: 5
kill_zdm
может ответ не поможет. я СУБД использую только как Хранилище инфы, а работу с ней реализую Средствами разработки, Delphi, напирмер. в паскале,как и в других языках программирования есть реализация работы со строками. Вот ты-быеще уточнил, как выглядит твой string


Пожалуйста!

КРАСНЫХ ЗОРЬ УЛ. 11 11
УКРАИНА ЛУГАНСКАЯ ОБЛ. СТАХАНОВ 60-ЛЕТИЯ ОКТЯБРЯ 11 11
ОТРАДНАЯ УЛ. 11 111 ОТРАДНАЯ УЛ. 11-111
г.Москва, Пречистенка 11/11 к.1 кв.38
МОЖАЙСКОЕ ШОССЕ 1 1 111
ЛЕТЧИКА БАБУШКИНА УЛ. 1 1 11 ЛЕТЧИКА БАБУШКИНА УЛ. 1 кор.1-11 ЛЕТЧИКА БАБУШКИНА УЛ. 1-1-11
МОСКВА ЮЗАО ГРИНА УЛ. 1 11 РОССИЯ МОСКВА ЮЗАО ГРИНА УЛ. 1 11
МОЖАЙСКОЕ ШОССЕ 1 11

и вот так еще с разделителем ","
111111,Москва,Карельский б-р,1,,11
,[NULL],[NULL],,[NULL],
МОСКВА СУЩЕВСКИЙ ВАЛ УЛ. 11 111 РОССИЯ МОСКВА СУЩЕВСКИЙ ВАЛ УЛ. 11 111 Сущевский вал, 11-111

Бардак полный одним словом. А надо конфетку сделать. Ясное дело, что 100% разобрать не получиться. Но 70% уже было бы прилично...
11 май 07, 14:23    [4126214]     Ответить | Цитировать Сообщить модератору
 Re: Скрипт разбора адресной строки  [new]
eggman
Member

Откуда:
Сообщений: 5
SQL*Plus
Договорились?


договорились :)
11 май 07, 14:24    [4126228]     Ответить | Цитировать Сообщить модератору
 Re: Скрипт разбора адресной строки  [new]
Strelets12
Guest
Скрипт не получится, может получиться большой пакет :(
Есть коммерческое ПО, насколько я знаю, стоит несколько килобаксов.
11 май 07, 15:03    [4126521]     Ответить | Цитировать Сообщить модератору
 Re: Скрипт разбора адресной строки  [new]
eggman
Member

Откуда:
Сообщений: 5
Strelets12
Скрипт не получится, может получиться большой пакет :(
Есть коммерческое ПО, насколько я знаю, стоит несколько килобаксов.


Да, я неправлиьно выразился. Скриптом тут конечно не ограничишься.

несколько килобаксов вариант не подходит мне. :(
11 май 07, 15:14    [4126584]     Ответить | Цитировать Сообщить модератору
 Re: Скрипт разбора адресной строки  [new]
eggman
Member

Откуда:
Сообщений: 5
Бабичев Сергей
Тынц - разбиение строк на лексемы, может чем поможет


поможет, но не сильно. :)
Это ж подзадачка маленькая
11 май 07, 15:15    [4126591]     Ответить | Цитировать Сообщить модератору
 Re: Скрипт разбора адресной строки  [new]
valerytin
Member [заблокирован]

Откуда: Moscow
Сообщений: 146
См.
11 май 07, 15:27    [4126683]     Ответить | Цитировать Сообщить модератору
 Re: Скрипт разбора адресной строки  [new]
Bely
Member

Откуда: Москва
Сообщений: 1903
eggman
Бабичев Сергей
Тынц - разбиение строк на лексемы, может чем поможет


поможет, но не сильно. :)
Это ж подзадачка маленькая
а дальше начинается перебор вариантов написания бардачных адресов и "угадывание" по значениям лексем тип поля.
типа - 6 цифр в начале адреса - индекс.
7 цифр - какой-то м... вбил телефон.
11 май 07, 17:06    [4127520]     Ответить | Цитировать Сообщить модератору
 Re: Скрипт разбора адресной строки  [new]
SQL*Plus
Member

Откуда: Россия, Москва
Сообщений: 8132
eggman
SQL*Plus
Договорились?
договорились :)
ОК. Ждем.
P.S. Я не забуду. :-)
11 май 07, 17:09    [4127548]     Ответить | Цитировать Сообщить модератору
 Re: Скрипт разбора адресной строки  [new]
ГостЪ
Guest
kill_zdm
может ответ не поможет. я СУБД использую только как Хранилище инфы, а работу с ней реализую Средствами разработки, Delphi, напирмер. в паскале,как и в других языках программирования есть реализация работы со строками. Вот ты-быеще уточнил, как выглядит твой string


Жуткая брань, тыбыещё, запомним
11 май 07, 21:38    [4128505]     Ответить | Цитировать Сообщить модератору
 Re: Скрипт разбора адресной строки  [new]
Bely
Member

Откуда: Москва
Сообщений: 1903
SQL*Plus
ОК. Ждем.
P.S. Я не забуду. :-)

Вот, занимался похожей проблемой - создал парсер адреса с разделенными через запятую.
Доделал только что, тестирование жизнью пока не было

Тестовые данные:


SELECT * FROM table(addr_util.parse_addr('107140, г. Москва, а/я 19'))
union all
SELECT * FROM table(addr_util.parse_addr('107140, г. Москва, ул. Краснопрудная, д. 22-А, оф 15'))
union all
SELECT * FROM table(addr_util.parse_addr('111111,  Алтай , г. Горно-Алтайск, 1-ый Рижский пер., дом 6 стр. 6, Павильон 14А, 15 минут пешком'))
union all
SELECT * FROM table(addr_util.parse_addr('111111,  Алтай , г. Горно-Алтайск, 1-ый Рижский пер., дом 6 стр. 6, кв 14, Павильон "Восток", 15 минут пешком'))
union all
SELECT * FROM table(addr_util.parse_addr('111111, республика  Алтай , г. Горно-Алтайск, 1-ый Рижский пер., дом 6, стр. 6 оф 18'))
union all
SELECT * FROM table(addr_util.parse_addr('111111, г. Горно-Алтайск, 1-ый Рижский пер., дом 6 стр. 6 оф. 14'))
union all
SELECT * FROM table(addr_util.parse_addr('111111, Горно-Алтайск, 1-ый Рижский пер., дом 6, стр. 6'))
union all
SELECT * FROM table(addr_util.parse_addr('222222, Корякский АО, Петропавловск-Камчатский, 1-ый Рижский пер., влад.3, стр. 6, оф.12'))
union all
SELECT * FROM table(addr_util.parse_addr('222222, Корякский автономный округ, Петропавловск-Камчатский, 1-ый Рижский пер., дом 6, стр. 6'))
union all
SELECT * FROM table(addr_util.parse_addr('222222, Корякский, Петропавловск-Камчатский, 1-ый Рижский пер., дом 6, стр. 6'))
union all
SELECT * FROM table(addr_util.parse_addr('222222, Петропавловск-Камчатский, 1-ый Рижский пер., дом 6, стр. 6'))
union all
SELECT * FROM table(addr_util.parse_addr('г. Москва, ул. Краснопрудная, д. 22-А'))
union all
SELECT * FROM table(addr_util.parse_addr('603074, г. Нижний Новгород, ул. Шаляпина, 2 а'))
union all
SELECT * FROM table(addr_util.parse_addr('г. Нижний Новгород, ул. Шаляпина, 2 а'))
union all
SELECT * FROM table(addr_util.parse_addr('129626, Россия, г. Москва, 1-ый Рижский пер., дом 6, стр. 6'))
union all
SELECT * FROM table(addr_util.parse_addr('391539, Рязанская обл., Шиловский р-он, п. Лесной'))
union all
SELECT * FROM table(addr_util.parse_addr('384000, г. Cочи, ул. Цв.Бульвар, 21-22'))
union all
SELECT * FROM table(addr_util.parse_addr('420029, Республика Татарстан, г. Казань, ул. Журналистов, д. 6'))
union all
SELECT * FROM table(addr_util.parse_addr('420061, г. Казань, а/я 3'))
union all
SELECT * FROM table(addr_util.parse_addr('416154, Астраханская обл., Красноярский р-н, п. Аксарайский'))
union all
SELECT * FROM table(addr_util.parse_addr('119991, ГСП-1, Москва, Ленинский пр-т., 65'))
union all
SELECT * FROM table(addr_util.parse_addr(' , г. Cочи, ул. Цв.Бульвар, 21-22'))
union all
SELECT * FROM table(addr_util.parse_addr(' , Астраханская обл., Красноярский р-н, п. Аксарайский'))
union all
SELECT * FROM table(addr_util.parse_addr(' , Россия, г. Москва, 1-ый Рижский пер., дом 6, стр. 6'))
union all
SELECT * FROM table(addr_util.parse_addr('129626,  , г. Москва, 1-ый Рижский пер., дом 6, стр. 6'))


результат.
ZIPREGIONREGION_IDDISTRICTDISTRICT_IDCITYSTREET_TYPESTREET_NAMEHOUSEBUILDINGOFFICEADDR_NOTEADDR_ID
107140г. Москваа/я 19
107140г. Москваул. Краснопруднаяд. 22-Аоф 15
111111Алтай5659г. Горно-Алтайск1-ый Рижский пер.дом 6 стр. 6Павильон 14А15 минут пешком
111111Алтай5659г. Горно-Алтайск1-ый Рижский пер.дом 6 стр. 6кв 14"Павильон ""Восток""; 15 минут пешком"
111111республика Алтай5659г. Горно-Алтайск1-ый Рижский пер.дом 6стр. 6 оф 18
111111г. Горно-Алтайск1-ый Рижский пер.дом 6 стр. 6 оф. 14
111111Горно-Алтайск1-ый Рижский пер.дом 6стр. 6
222222Корякский АО5687Петропавловск-Камчатский1-ый Рижский пер.влад.3; стр. 6оф.12
222222Корякский автономный округ5687Петропавловск-Камчатский1-ый Рижский пер.дом 6стр. 6
222222Корякский5687Петропавловск-Камчатский1-ый Рижский пер.дом 6стр. 6
222222Петропавловск-Камчатский1-ый Рижский пер.дом 6стр. 6
г. Москваул. Краснопруднаяд. 22-А
603074г. Нижний Новгородул. Шаляпина2 а
г. Нижний Новгородул. Шаляпина2 а
129626г. Москва1-ый Рижский пер.дом 6стр. 6Россия
391539Рязанская обл.Шиловский р-он7219п. Лесной
384000г. Cочиул. Цв.Бульвар21-22
420029Республика Татарстанг. Казаньул. Журналистовд. 6
420061г. Казаньа/я 3
416154Астраханская обл.Красноярский р-н6443п. Аксарайский
119991Москва5654Ленинский пр-т.65ГСП-1
г. Cочиул. Цв.Бульвар21-22
Астраханская обл.Красноярский р-н6443п. Аксарайский
г. Москва1-ый Рижский пер.дом 6стр. 6Россия
129626г. Москва1-ый Рижский пер.дом 6стр. 6


Желающие могут достругивать по своему усмотрению под свои адреса.

Теперь исходники

Текст пакета
-- Start of DDL Script for Package DC_ANKETA_DEV.ADDR_UTIL
-- Generated 23-май-2007 12:08:05 from DC_ANKETA_DEV@CRM.DIRECTCONTACT.RU

CREATE OR REPLACE 
PACKAGE addr_util
IS
    -- Removes duplicate spaces --
    FUNCTION remove_waste_spaces (I_s_str IN VARCHAR2)
    RETURN VARCHAR2;

    -- Creates token table (c) --
    FUNCTION create_token_table (I_s_str IN VARCHAR2, s_sep_list IN VARCHAR2 default ' ,.''"-')
    RETURN t_table;

    -- Fix address --
    FUNCTION fix_address (I_s_addr IN VARCHAR2, I_s_Categ IN VARCHAR2 default 'FixAddress',
                          I_s_sep_list IN VARCHAR2 default ' ,.''"-')
    RETURN VARCHAR2;


FUNCTION parse_addr(I_s_str IN VARCHAR2)   RETURN tb_addr_struct;
-- ==================================================================
--  Функция разбирает адрес и возвращает структуру с заполненными полями.
--  Поля в адресе должны быть разделены запятыми.
-- ==================================================================

END;
/

-- Grants for Package
GRANT EXECUTE ON addr_util TO dc_anketa_wrk_dev
/

CREATE OR REPLACE 
PACKAGE BODY addr_util
IS

-- Address parse - state constants --
ADU_PARSE_ST_NONE     constant NUMBER := 0;
ADU_PARSE_ST_ZIP      constant NUMBER := 1;
ADU_PARSE_ST_REGION   constant NUMBER := 2;
ADU_PARSE_ST_DISTRICT constant NUMBER := 4;
ADU_PARSE_ST_CITY     constant NUMBER := 8;
ADU_PARSE_ST_STREET   constant NUMBER := 16;
ADU_PARSE_ST_HOUSE    constant NUMBER := 32;
ADU_PARSE_ST_BUILD    constant NUMBER := 64;
ADU_PARSE_ST_OFFICE   constant NUMBER := 128;
ADU_PARSE_ST_NOTE     constant NUMBER := 256;
ADU_PARSE_ST_NOTE_PRE constant NUMBER := 512;

--  =================================================================
    FUNCTION remove_waste_spaces (I_s_str IN VARCHAR2)
    RETURN VARCHAR2
    IS
        beg_w NUMBER := 1;
        end_w NUMBER := 0;	
        result VARCHAR2 (2000);
	
    BEGIN
        -- Return immedietly when NULL in input string --
        IF I_s_str IS NULL THEN RETURN NULL; END IF;

        -- Process string --
        <<get_next_word>>
	    LOOP
            end_w := INSTR (I_s_str, ' ', beg_w);
		
            IF (end_w = 0)
            THEN
                end_w := LENGTH (I_s_str) + 1;
            END IF;
		
            IF (beg_w != end_w)
            THEN
                result := result || SUBSTR (I_s_str, beg_w, end_w - beg_w) || ' ';
            END IF;
    	
            beg_w := end_w + 1;
		
            EXIT get_next_word WHEN (beg_w >= LENGTH (I_s_str) + 1);	
        END LOOP;
	
        RETURN result;
	
    EXCEPTION
        WHEN OTHERS THEN
            DECLARE
                err_num NUMBER         := SQLCODE;
                err_msg VARCHAR2 (512) := SQLERRM;
            BEGIN
                DBMS_OUTPUT.put_line ('ADDR_UTIL.REMOVE_WASTE_SPACES::Error: (' || err_num || ') - ' || err_msg);
                RETURN NULL;
            END;

    END remove_waste_spaces;
--  =================================================================


--  =================================================================
    FUNCTION create_token_table (I_s_str IN VARCHAR2, s_sep_list IN VARCHAR2 default ' ,.''"-')
    RETURN t_table
    IS
        tkn  t_token := t_token(NULL,NULL,NULL);
        ttbl t_table := t_table ();
        tmp  NUMBER := 0;
        tbeg NUMBER := 1;
        tend NUMBER := 1;
        ttyp CHAR;

    BEGIN
        -- Return if input string is NULL --
        IF I_s_str IS NULL THEN RETURN NULL; END IF;

        <<build_table>>
        LOOP
            tmp := INSTR (s_sep_list, SUBSTR (I_s_str, tend, 1));

            -- If current symbol is in list of separator --
            IF (tmp != 0)
            THEN
                ttyp := 'S';

                <<token_s_walk>>
                LOOP
                    tend := tend + 1;
                    tmp := INSTR (s_sep_list, SUBSTR (I_s_str, tend, 1));
                    EXIT token_s_walk WHEN (tmp = 0 OR tend > LENGTH (I_s_str));
                END LOOP;
            ELSE
                ttyp := 'W';

                <<token_w_walk>>
                LOOP
                    tend := tend + 1;
                    tmp := INSTR (s_sep_list, SUBSTR (I_s_str, tend, 1));
                    EXIT token_w_walk WHEN (tmp != 0 OR tend > LENGTH (I_s_str));
                END LOOP;
            END IF;

            tkn.tbeg := tbeg;
            tkn.tend := tend;
            tkn.ttyp := ttyp;

            ttbl.EXTEND;
            ttbl (ttbl.LAST) := tkn;

            tbeg := tend;

            EXIT build_table  WHEN (tbeg >= LENGTH (I_s_str));
        END LOOP;

        RETURN ttbl;

    EXCEPTION
        WHEN OTHERS THEN
            DECLARE
                err_num NUMBER         := SQLCODE;
                err_msg VARCHAR2 (512) := SQLERRM;
            BEGIN
                DBMS_OUTPUT.put_line ('ADDR_UTIL.CREATE_TOKEN_TABLE::Error: (' || err_num || ') - ' || err_msg);
                RETURN NULL;
            END;

    END create_token_table;
--  =================================================================

--  =================================================================
    FUNCTION fix_address (I_s_addr IN VARCHAR2, I_s_Categ IN VARCHAR2 default 'FixAddress',
                          I_s_sep_list IN VARCHAR2 default ' ,.''"-')
    RETURN VARCHAR2
    IS
        buf VARCHAR2 (2000);
        ret VARCHAR2 (2000);
        tbl t_table;
        tkn t_token;
        wrd VARCHAR2 (500);
        rep VARCHAR2 (500);
        i   NUMBER;

        CURSOR cur_replace (s_repl VARCHAR2) IS
            SELECT   sr.dest_val
            FROM     str_replace  sr
            WHERE    sr.replaced = s_repl
            AND      sr.categ = I_s_Categ
            ORDER BY sr.rank;

    BEGIN
        -- Return if address string is NULL --
        IF I_s_addr IS NULL THEN RETURN NULL; END IF;

        buf := remove_waste_spaces (I_s_addr);
        tbl := create_token_table (buf,I_s_sep_list);

        FOR i IN 1 .. tbl.COUNT
        LOOP
            tkn := tbl (i);

            -- If current token is separator
            -- we simply append it to result string
            IF (tkn.ttyp = 'S')
            THEN
                ret := ret || SUBSTR (buf, tkn.tbeg, tkn.tend - tkn.tbeg);

            -- Else, we are searching for replace --
            ELSIF (tkn.ttyp = 'W')
            THEN
                wrd := SUBSTR (buf, tkn.tbeg, tkn.tend - tkn.tbeg);
                ------
                OPEN  cur_replace (wrd);
                FETCH cur_replace INTO rep;

                IF (cur_replace%FOUND)
                THEN
                    -- If replace found, append it to result string --
                    ret := ret || rep;
                ELSE
                    -- Else, append token
        	        ret := ret || wrd;
                END IF;

                CLOSE cur_replace;
                -----
            END IF;
        END LOOP;

        RETURN ret;

    EXCEPTION
        WHEN OTHERS THEN
            DECLARE
                err_num NUMBER         := SQLCODE;
                err_msg VARCHAR2 (512) := SQLERRM;
            BEGIN
                DBMS_OUTPUT.put_line ('ADDR_UTIL.FIX_ADDRESS::Error: (' || err_num || ') - ' || err_msg);
                RETURN NULL;
            END;

    END fix_address;
--  =================================================================


--  =================================================================
--  Эта функция проверяет наличие токенов во входном слове.
--  Сравнение происходит без учета регистра
--  Входные параметры:
--    I_sz_INP_STR    - входная строка
--    I_sz_CATEG_ABBR - название категории в таблице SIMPLE_LIST, в которой
--                      находятся токены для поиска
--    I_sz_SEP_LIST   - строка с разделителями
--  Возвращаемое значение: NUMBER
--    0 - ничего не найдено
--    1 - токен найден
--  =================================================================
FUNCTION  is_token_exist(I_sz_INP_STR IN VARCHAR2, I_sz_CATEG_ABBR IN VARCHAR2,
                         I_sz_SEP_LIST IN VARCHAR2 default ' .')
          RETURN NUMBER
IS
  n_ret NUMBER := 0;
BEGIN
  -- Process each token --
  for rec in (SELECT trim(substr(I_sz_INP_STR,t.tbeg,tend-t.tbeg)) as VAL
              FROM table(addr_util.create_token_table(I_sz_INP_STR,I_sz_SEP_LIST)) t
              WHERE ttyp = 'W')
  loop
    -- Search token in ABBREVIATION list --
    for r in (SELECT * FROM simple_list sl
              WHERE sl.categ_name = I_sz_CATEG_ABBR and sl.icheck = 0
                and Upper(sl.name) = Upper(rec.VAL))
    loop
      -- Token found --
      n_ret := 1;
      exit;
    end loop;
    -- Exit, if token Found --
    exit when n_ret <> 0;
  end loop; -- End of for each token
  
  return n_ret;
END; -- is_token_exist()
--  =================================================================


--  =================================================================
--  Эта функция проверяет название региона и возвращает REGION_ID.
--  Сравнение происходит без учета регистра
--  Входные параметры:
--    I_sz_INP_STR       - входная строка
--    I_sz_CATEG_REGION  - название категории в таблице SIMPLE_LIST, в которой
--                         находbтся список регионов
--    I_sz_CATEG_REPLACE - строка с заменами слов в названиях регионов
--  Возвращаемое значение: NUMBER
--    NULL      - ничего не найдено
--    REGION_ID - ID региона в таблице SIMPLE_LIST
--  =================================================================
FUNCTION get_region_id(I_sz_INP_STR IN VARCHAR2, I_sz_CATEG_REGION IN VARCHAR2,
                       I_sz_CATEG_DST_REPLACE IN VARCHAR2, I_sz_CATEG_SRC_REPLACE IN VARCHAR2)
          RETURN NUMBER
IS
  n_ret NUMBER := NULL;
  sz_inp_region SIMPLE_LIST.name%TYPE;
BEGIN
  -- Process input REGION name, remove abbreviations --
  sz_inp_region := Upper(trim(addr_util.fix_address(I_sz_INP_STR,I_sz_CATEG_SRC_REPLACE,' ')));
  
  for rec in (SELECT sl.* FROM simple_list sl
              WHERE sl.categ_name = I_sz_CATEG_REGION
                and Upper(trim(addr_util.fix_address(sl.name,I_sz_CATEG_DST_REPLACE,' '))) = sz_inp_region)
  loop
    n_ret := rec.id;
    exit;
  end loop;
  return n_ret;
END; -- get_region_id()
--  =================================================================


--  =================================================================
FUNCTION parse_addr(I_s_str IN VARCHAR2)  RETURN tb_addr_struct
IS
  n_last_state NUMBER := ADU_PARSE_ST_NONE;
  n_all_state  NUMBER := ADU_PARSE_ST_NONE;
  r_addr  r_addr_struct  := r_addr_struct(NULL,NULL,NULL,NULL,NULL,
                                          NULL,NULL,NULL,NULL,NULL,
                                          NULL,NULL,NULL);
  t_addr  tb_addr_struct := tb_addr_struct();
  n_tmp  NUMBER;
  sz_tmp VARCHAR2(200);
  is_skip  BOOLEAN;
  is_found BOOLEAN;

function bitor(p_dec1 number, p_dec2 number) return number is
begin
  return p_dec1-bitand(p_dec1,p_dec2)+p_dec2;
end;
  
BEGIN

  for rec in (SELECT trim(substr(I_s_str,t.tbeg,tend-t.tbeg)) as VAL
              FROM table(addr_util.create_token_table(I_s_str,',')) t
              WHERE ttyp = 'W')
  loop
    -- Set SKIP flag to OFF --
    is_skip := False;
    
    -- Skip empty word --
    if trim(rec.VAL) is NULL then
      is_skip := True;
    end if;
    
    -- ZIP code - should be first --
    if (n_last_state = ADU_PARSE_ST_NONE)
       and (bitand(n_all_state,ADU_PARSE_ST_ZIP)=0) and NOT is_skip
    then
      begin
        n_tmp := to_number(rec.VAL);
      exception
      when INVALID_NUMBER OR VALUE_ERROR then
        n_tmp := -1;
      end;
      -- ZIP code found --
      if (n_tmp > 99999) and (n_tmp < 1000000) then
        r_addr.zip := rec.VAL;
        n_last_state := ADU_PARSE_ST_ZIP;
        n_all_state  := bitor(n_all_state,ADU_PARSE_ST_ZIP);
        is_skip := True;
      end if;
    end if;

    -- Parse REGION --
    if     (n_last_state in (ADU_PARSE_ST_NONE,ADU_PARSE_ST_ZIP))
       and (bitand(n_all_state,ADU_PARSE_ST_REGION)=0) and NOT is_skip
    then
      -- Test for REGION (search abbreviation) --
      if is_token_exist(rec.VAL,'REGION_ABBREV') <> 0 then
        -- Save REGION info --
        r_addr.region := rec.VAL;
        r_addr.region_id := get_region_id(rec.VAL,'SFCL_SF_LIST','REGION_ABBREV','REGION_REPL');
        n_last_state  := ADU_PARSE_ST_REGION;
        n_all_state   := bitor(n_all_state,ADU_PARSE_ST_REGION);
        is_skip := True;
      -- Test for REGION names --
      else
        n_tmp := get_region_id(rec.VAL,'SFCL_SF_LIST','REGION_ABBREV','REGION_REPL');
        if n_tmp <> 0 then
          -- Save REGION info --
          r_addr.region    := rec.VAL;
          r_addr.region_id := n_tmp;
          n_last_state  := ADU_PARSE_ST_REGION;
          n_all_state   := bitor(n_all_state,ADU_PARSE_ST_REGION);
          is_skip := True;
        end if;
      end if;

    end if;


    -- Parse DISTRICT --
    if     (n_last_state in (ADU_PARSE_ST_REGION))
       and (bitand(n_all_state,ADU_PARSE_ST_DISTRICT)=0) and NOT is_skip
    then
      -- Test for DISTRICT (search abbreviation) --
      if is_token_exist(rec.VAL,'DISTRICT_ABBREV') <> 0 then
        -- Save DISTRICT info --
        r_addr.district := rec.VAL;
        r_addr.district_id := get_region_id(rec.VAL,'SFCL_DISTRICT_LIST','DISTRICT_ABBREV','DISTRICT_REPL');
        n_last_state  := ADU_PARSE_ST_DISTRICT;
        n_all_state   := bitor(n_all_state,ADU_PARSE_ST_DISTRICT);
        is_skip := True;
      -- Test for DISTRICT names --
      else
        n_tmp := get_region_id(rec.VAL,'SFCL_DISTRICT_LIST','DISTRICT_ABBREV','DISTRICT_REPL');
        if n_tmp <> 0 then
          -- Save DISTRICT info --
          r_addr.district    := rec.VAL;
          r_addr.district_id := n_tmp;
          n_last_state  := ADU_PARSE_ST_DISTRICT;
          n_all_state   := bitor(n_all_state,ADU_PARSE_ST_DISTRICT);
          is_skip := True;
        end if;
      end if;

    end if;

    -- Parse CITY --
    if     (n_last_state in (ADU_PARSE_ST_NONE,ADU_PARSE_ST_ZIP,ADU_PARSE_ST_REGION,ADU_PARSE_ST_REGION,ADU_PARSE_ST_DISTRICT))
       and (bitand(n_all_state,ADU_PARSE_ST_CITY)=0) and NOT is_skip
    then
      -- Test for CITY (search abbreviation) --
      if is_token_exist(rec.VAL,'CITY_ABBREV') <> 0 then
        -- Save CITY info --
        r_addr.city := rec.VAL;
--        r_addr.city_id := get_region_id(rec.VAL,'SFCL_CITY_LIST','CITY_ABBREV','CITY_REPL');
        n_last_state  := ADU_PARSE_ST_CITY;
        n_all_state   := bitor(n_all_state,ADU_PARSE_ST_CITY);
        is_skip := True;
      -- Test for DISTRICT names --
      else
        n_tmp := get_region_id(rec.VAL,'SFCL_CITY_LIST','CITY_ABBREV','CITY_REPL');
        if n_tmp <> 0 then
          -- Save CITY info --
          r_addr.city    := rec.VAL;
--          r_addr.city_id := n_tmp;
          n_last_state  := ADU_PARSE_ST_CITY;
          n_all_state   := bitor(n_all_state,ADU_PARSE_ST_CITY);
          is_skip := True;
        end if;
      end if;
    end if;

    -- Parse STREET --
    if     (n_last_state in (ADU_PARSE_ST_REGION,ADU_PARSE_ST_CITY))
       and (bitand(n_all_state,ADU_PARSE_ST_STREET)=0) and NOT is_skip
    then
      -- Test for STREET (search abbreviation) --
      if is_token_exist(rec.VAL,'STREET_ABBREV') <> 0 then
        -- Save STREET info --
        r_addr.street_name := trim(addr_util.fix_address(rec.VAL,'STREET_ABBREV',' .'));
        r_addr.street_type := trim(replace(rec.VAL,r_addr.street_name));
        n_last_state  := ADU_PARSE_ST_STREET;
        n_all_state   := bitor(n_all_state,ADU_PARSE_ST_STREET);
        is_skip := True;
      end if;
    end if;
    
    -- Parse SPECIAL CASES --
    if     (n_last_state in (ADU_PARSE_ST_REGION,ADU_PARSE_ST_CITY,ADU_PARSE_ST_STREET))
       and (bitand(n_all_state,ADU_PARSE_ST_BUILD)=0) and NOT is_skip
    then
      -- Test for "А/Я" --
      if instr(Upper(rec.VAL),'А/Я') > 0 then
        -- Save info --
        r_addr.building := rec.VAL;
        n_last_state  := ADU_PARSE_ST_NOTE_PRE;
        n_all_state   := bitor(n_all_state,ADU_PARSE_ST_BUILD);
        n_all_state   := bitor(n_all_state,ADU_PARSE_ST_NOTE);
        is_skip := True;
      end if;
    end if;

    -- Parse HOUSE --
    if     (n_last_state in (ADU_PARSE_ST_STREET))
       and (bitand(n_all_state,ADU_PARSE_ST_HOUSE)=0) and NOT is_skip
    then
      -- Test for HOUSE (search abbreviation) --
      if is_token_exist(rec.VAL,'HOUSE_ABBREV') <> 0 then
        -- Save HOUSE info --
        r_addr.house  := rec.VAL;
        n_last_state  := ADU_PARSE_ST_HOUSE;
        n_all_state   := bitor(n_all_state,ADU_PARSE_ST_HOUSE);
        is_skip := True;
        
      -- Check for BUILDING. If found - skip action, otherwise - treat data as HOUSE --
      elsif is_token_exist(rec.VAL,'BUILDING_ABBREV') = 0 then
        -- Save HOUSE info --
        r_addr.house  := rec.VAL;
        n_last_state  := ADU_PARSE_ST_HOUSE;
        n_all_state   := bitor(n_all_state,ADU_PARSE_ST_HOUSE);
        is_skip := True;
      end if;
      
    end if;

    -- Parse BUILDING --
    if     (n_last_state in (ADU_PARSE_ST_STREET,ADU_PARSE_ST_HOUSE,ADU_PARSE_ST_BUILD))
       and NOT is_skip
    then
      -- Test for BUILDING (search abbreviation) --
      if is_token_exist(rec.VAL,'BUILDING_ABBREV') <> 0 then
        -- Add BUILDING info --
        if r_addr.building is NOT NULL then
          r_addr.building := r_addr.building||', ';
        end if;
        r_addr.building  := r_addr.building||rec.VAL;
        n_last_state  := ADU_PARSE_ST_BUILD;
        n_all_state   := bitor(n_all_state,ADU_PARSE_ST_BUILD);
        is_skip := True;
      end if;
    end if;

    -- Parse OFFICE --
    if     (n_last_state in (ADU_PARSE_ST_HOUSE,ADU_PARSE_ST_BUILD))
       and (bitand(n_all_state,ADU_PARSE_ST_OFFICE)=0) and NOT is_skip
    then
      -- Test for OFFICE (search abbreviation) --
      if is_token_exist(rec.VAL,'OFFICE_ABBREV') <> 0 then
        -- Save OFFICE info --
        r_addr.office := rec.VAL;
        n_last_state  := ADU_PARSE_ST_OFFICE;
        n_all_state   := bitor(n_all_state,ADU_PARSE_ST_OFFICE);
        is_skip := True;
      end if;
    end if;

    -- Add string to ADDR_NOTE (other) --
    if (n_last_state in (ADU_PARSE_ST_NOTE)) or (NOT is_skip)
    then
      if r_addr.addr_note is NOT NULL then
        r_addr.addr_note := r_addr.addr_note||', ';
      end if;
      r_addr.addr_note := r_addr.addr_note||rec.VAL;
      n_all_state   := bitor(n_all_state,ADU_PARSE_ST_NOTE);
      is_skip := True;
      if n_last_state in (ADU_PARSE_ST_CITY, ADU_PARSE_ST_STREET, ADU_PARSE_ST_HOUSE,
                          ADU_PARSE_ST_BUILD, ADU_PARSE_ST_OFFICE)
      then
        n_last_state := ADU_PARSE_ST_NOTE;
      end if;
    elsif n_last_state in (ADU_PARSE_ST_NOTE_PRE) then
      n_last_state := ADU_PARSE_ST_NOTE;
    end if;


  end loop;
  
  t_addr.extend;
  t_addr(t_addr.last) := r_addr;
  return t_addr;
  
END; -- parse_addr()
--  =================================================================


END;
/

создание структур и заполнение данных.

CREATE OR REPLACE 
TYPE r_addr_struct IS OBJECT  
( ZIP         NUMBER, 
  REGION      VARCHAR2(100), 
  REGION_ID   NUMBER, 
  DISTRICT    VARCHAR2(100), 
  DISTRICT_ID NUMBER, 
  CITY        VARCHAR2(200), 
  STREET_TYPE VARCHAR2(50), 
  STREET_NAME VARCHAR2(100), 
  HOUSE       VARCHAR2(100), 
  BUILDING    VARCHAR2(100), 
  OFFICE      VARCHAR2(100), 
  ADDR_NOTE   VARCHAR2(600),
  ADDR_ID     NUMBER
);
/

CREATE OR REPLACE 
TYPE tb_addr_struct IS TABLE OF r_addr_struct;
/



INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('REGION_ABBREV','респ',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('REGION_ABBREV','республика',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('REGION_ABBREV','рес',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('REGION_ABBREV','обл',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('REGION_ABBREV','край',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('REGION_ABBREV','область',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('REGION_ABBREV','АО',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('REGION_ABBREV','автономный',0)
/




INSERT INTO STR_REPLACE
(CATEG, REPLACED, DEST_VAL ) VALUES ('REGION_ABBREV','обл.','')
/
INSERT INTO STR_REPLACE
(CATEG, REPLACED, DEST_VAL ) VALUES ('REGION_ABBREV','респ.','')
/
INSERT INTO STR_REPLACE
(CATEG, REPLACED, DEST_VAL ) VALUES ('REGION_ABBREV','край','')
/
INSERT INTO STR_REPLACE
(CATEG, REPLACED, DEST_VAL ) VALUES ('REGION_ABBREV','АО','')
/


INSERT INTO STR_REPLACE
(CATEG, REPLACED, DEST_VAL ) VALUES ('REGION_REPL','респ','')
/
INSERT INTO STR_REPLACE
(CATEG, REPLACED, DEST_VAL ) VALUES ('REGION_REPL','республика','')
/
INSERT INTO STR_REPLACE
(CATEG, REPLACED, DEST_VAL ) VALUES ('REGION_REPL','рес','')
/
INSERT INTO STR_REPLACE
(CATEG, REPLACED, DEST_VAL ) VALUES ('REGION_REPL','обл','')
/
INSERT INTO STR_REPLACE
(CATEG, REPLACED, DEST_VAL ) VALUES ('REGION_REPL','край','')
/
INSERT INTO STR_REPLACE
(CATEG, REPLACED, DEST_VAL ) VALUES ('REGION_REPL','область','')
/
INSERT INTO STR_REPLACE
(CATEG, REPLACED, DEST_VAL ) VALUES ('REGION_REPL','АО','')
/
INSERT INTO STR_REPLACE
(CATEG, REPLACED, DEST_VAL ) VALUES ('REGION_REPL','автономный','')
/
INSERT INTO STR_REPLACE
(CATEG, REPLACED, DEST_VAL ) VALUES ('REGION_REPL','округ','')
/


-- ==================== District DATA ====================

INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('DISTRICT_ABBREV','р-н',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('DISTRICT_ABBREV','район',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('DISTRICT_ABBREV','р-он',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('DISTRICT_ABBREV','р.',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('DISTRICT_ABBREV','улус',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('DISTRICT_ABBREV','у',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('DISTRICT_ABBREV','у.',0)
/


-- =================================================

INSERT INTO STR_REPLACE
(CATEG, REPLACED, DEST_VAL ) VALUES ('DISTRICT_ABBREV','р-н','')
/
INSERT INTO STR_REPLACE
(CATEG, REPLACED, DEST_VAL ) VALUES ('DISTRICT_ABBREV','у.','')
/
INSERT INTO STR_REPLACE
(CATEG, REPLACED, DEST_VAL ) VALUES ('DISTRICT_ABBREV','у','')
/


INSERT INTO STR_REPLACE
(CATEG, REPLACED, DEST_VAL ) VALUES ('DISTRICT_REPL','р-н','')
/
INSERT INTO STR_REPLACE
(CATEG, REPLACED, DEST_VAL ) VALUES ('DISTRICT_REPL','район','')
/
INSERT INTO STR_REPLACE
(CATEG, REPLACED, DEST_VAL ) VALUES ('DISTRICT_REPL','р-он','')
/
INSERT INTO STR_REPLACE
(CATEG, REPLACED, DEST_VAL ) VALUES ('DISTRICT_REPL','р.','')
/
INSERT INTO STR_REPLACE
(CATEG, REPLACED, DEST_VAL ) VALUES ('DISTRICT_REPL','улус','')
/
INSERT INTO STR_REPLACE
(CATEG, REPLACED, DEST_VAL ) VALUES ('DISTRICT_REPL','у','')
/
INSERT INTO STR_REPLACE
(CATEG, REPLACED, DEST_VAL ) VALUES ('DISTRICT_REPL','у.','')
/

-- ===================== CITY abbreviation ======================


INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('CITY_ABBREV','г',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('CITY_ABBREV','город',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('CITY_ABBREV','пгт',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('CITY_ABBREV','п',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('CITY_ABBREV','пос',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('CITY_ABBREV','поселок',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('CITY_ABBREV','д',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('CITY_ABBREV','дер',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('CITY_ABBREV','деревня',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('CITY_ABBREV','с',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('CITY_ABBREV','село',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('CITY_ABBREV','ст-ца',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('CITY_ABBREV','стан',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('CITY_ABBREV','станица',0)
/



INSERT INTO STR_REPLACE
(CATEG, REPLACED, DEST_VAL ) VALUES ('CITY_REPL','г.','')
/
INSERT INTO STR_REPLACE
(CATEG, REPLACED, DEST_VAL ) VALUES ('CITY_REPL','г','')
/
INSERT INTO STR_REPLACE
(CATEG, REPLACED, DEST_VAL ) VALUES ('CITY_REPL','город','')
/


-- =====================  STREET info  ======================


INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('STREET_ABBREV','ул',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('STREET_ABBREV','у',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('STREET_ABBREV','улица',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('STREET_ABBREV','пл',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('STREET_ABBREV','площадь',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('STREET_ABBREV','ш',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('STREET_ABBREV','шос',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('STREET_ABBREV','шоссе',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('STREET_ABBREV','пер',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('STREET_ABBREV','пер-к',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('STREET_ABBREV','переулок',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('STREET_ABBREV','пр-т',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('STREET_ABBREV','прос',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('STREET_ABBREV','просп',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('STREET_ABBREV','пр',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('STREET_ABBREV','проспект',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('STREET_ABBREV','пр-д',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('STREET_ABBREV','пр-зд',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('STREET_ABBREV','проезд',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('STREET_ABBREV','ал',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('STREET_ABBREV','аллея',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('STREET_ABBREV','кв-л',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('STREET_ABBREV','квар',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('STREET_ABBREV','кварт',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('STREET_ABBREV','квартал',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('STREET_ABBREV','наб',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('STREET_ABBREV','набер',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('STREET_ABBREV','набережная',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('STREET_ABBREV','мкрн',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('STREET_ABBREV','микр',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('STREET_ABBREV','микрорайон',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('STREET_ABBREV','б-р',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('STREET_ABBREV','бул',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('STREET_ABBREV','бульвар',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('STREET_ABBREV','туп',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('STREET_ABBREV','тупик',0)
/


-- ========================  HOUSE info ===============================

INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('HOUSE_ABBREV','д',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('HOUSE_ABBREV','дом',0)
/

-- ========================  BUILDING info ===============================
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('BUILDING_ABBREV','с',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('BUILDING_ABBREV','стр',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('BUILDING_ABBREV','строение',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('BUILDING_ABBREV','к',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('BUILDING_ABBREV','кор',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('BUILDING_ABBREV','корпус',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('BUILDING_ABBREV','вл',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('BUILDING_ABBREV','влад',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('BUILDING_ABBREV','владение',0)
/


-- ========================  OFFICE info ===============================
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('OFFICE_ABBREV','оф',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('OFFICE_ABBREV','офис',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('OFFICE_ABBREV','кв',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('OFFICE_ABBREV','квартира',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('OFFICE_ABBREV','ком',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('OFFICE_ABBREV','комната',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('OFFICE_ABBREV','мес',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('OFFICE_ABBREV','место',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('OFFICE_ABBREV','пав',0)
/
INSERT INTO SIMPLE_LIST 
(CATEG_NAME, NAME, ICHECK ) VALUES ('OFFICE_ABBREV','павильон',0)
/


commit
/


Структуры внутренних таблиц, которые использовались.
CREATE TABLE simple_list
    (id                            NUMBER(*,0) NOT NULL,
    created_date                   DATE,
    last_update_date               DATE,
    icheck                         NUMBER(*,0) DEFAULT 0,
    categ_name                     VARCHAR2(50),
    name                           VARCHAR2(250),
    rank                           NUMBER(*,0) DEFAULT 200,
    code_str                       VARCHAR2(50),
    parent_id                      NUMBER(*,0),
    param_str                      VARCHAR2(500))
/

CREATE TABLE str_replace
    (id                             NUMBER NOT NULL,
    categ                          VARCHAR2(200),
    replaced                       VARCHAR2(500),
    dest_val                       VARCHAR2(500),
    rank                           NUMBER DEFAULT 200,
    params                         VARCHAR2(1000))
/

23 май 07, 12:43    [4173712]     Ответить | Цитировать Сообщить модератору
 Re: Скрипт разбора адресной строки  [new]
andrey_anonymous
Member

Откуда: Москва
Сообщений: 18388
Хочу обратить внимание на такую публичную базочку от налоговиков как КЛАДР.
Может помочь выделять названия населенных пунктов и улиц, особенно если сумеете организовать проверку данных по КЛАДР при вводе
23 май 07, 13:17    [4174027]     Ответить | Цитировать Сообщить модератору
 Re: Скрипт разбора адресной строки  [new]
Bely
Member

Откуда: Москва
Сообщений: 1903
andrey_anonymous
Хочу обратить внимание на такую публичную базочку от налоговиков как КЛАДР.
Может помочь выделять названия населенных пунктов и улиц, особенно если сумеете организовать проверку данных по КЛАДР при вводе
Именно она у нас и использовалась для этого.
Это я забыл сказать.

Проблема есть с названиями улиц.
Не все пишут названия так, как принято в КЛАДР-е.
Кроме этого в КЛАДР-е есть не все адреса и названия улиц, которые реально встречаются в жизни.
Мы остановились на том, что из КЛАДР-а используем названия СФ и районов, частично названия НП.
Просто нас интересуют не все города, которые есть в КЛАДР-е.
23 май 07, 13:45    [4174362]     Ответить | Цитировать Сообщить модератору
 Re: Скрипт разбора адресной строки  [new]
andrey_anonymous
Member

Откуда: Москва
Сообщений: 18388
Bely
Проблема есть с названиями улиц.
Не все пишут названия так, как принято в КЛАДР-е.

Я потому и отметил особо валидацию по КЛАДР при вводе данных
Что до отсутствующих улиц/домов... Ну когда-то (много-много лет назад :) я просто расширил КЛАДР кастомной частью, куда и вписывал отсутстующие данные.
Предполагалось, что по мере освежения информации в КЛАДР кастомные данные будут замещаться КЛАДРовскими.
Правда я тогда уволился не закончив и проект умер :)
23 май 07, 13:49    [4174396]     Ответить | Цитировать Сообщить модератору
 Re: Скрипт разбора адресной строки  [new]
orawish
Member

Откуда: Гадюкино-2 (City)
Сообщений: 15487
andrey_anonymous
Хочу обратить внимание на такую публичную базочку от налоговиков как КЛАДР.
Может помочь выделять названия населенных пунктов и улиц, особенно если сумеете организовать проверку данных по КЛАДР при вводе

Точно, точно. И структуру хранения нормализовать - иначе никогда не отличите
Карякский округ от такого же переулка.. Задача гнилая. Вот знаете, например, что в москве есть
целые районы с адресом район-дом (без улицы).
Имхо, иначе (кроме как поиском не лексем, а словарных имен собственных, причем с учетом индивидуальной структуры последующей части адреса) не решается.. Разве что - ручками разобрать.
23 май 07, 13:56    [4174473]     Ответить | Цитировать Сообщить модератору
 Re: Скрипт разбора адресной строки  [new]
Bely
Member

Откуда: Москва
Сообщений: 1903
orawish
Вот знаете, например, что в москве есть
целые районы с адресом район-дом (без улицы).
Например? что за адреса такие?
Зеленоград знаю - там местами просто сквознаю нумерация домов.
А что еще?

orawish
Имхо, иначе (кроме как поиском не лексем, а словарных имен собственных, причем с учетом индивидуальной структуры последующей части адреса) не решается.. Разве что - ручками разобрать.
Вопрос упирается в проценты - сколько таких адресов.
Данная процедура сделана для упрощения обработки адресов, которые приносит клиент.
Это всеравно лучше, чем 2000 адресов разносить руками.
23 май 07, 14:11    [4174625]     Ответить | Цитировать Сообщить модератору
 Re: Скрипт разбора адресной строки  [new]
andrey_anonymous
Member

Откуда: Москва
Сообщений: 18388
orawish
иначе никогда не отличите

Неправда Ваша.
КЛАДР - это классификатор.
23 май 07, 14:31    [4174845]     Ответить | Цитировать Сообщить модератору
 Re: Скрипт разбора адресной строки  [new]
orawish
Member

Откуда: Гадюкино-2 (City)
Сообщений: 15487
Bely
orawish
Вот знаете, например, что в москве есть
целые районы с адресом район-дом (без улицы).
Например? что за адреса такие?
Зеленоград знаю - там местами просто сквознаю нумерация домов.
А что еще?

еще напр. Чертаново-Северное
Bely

orawish
Имхо, иначе (кроме как поиском не лексем, а словарных имен собственных, причем с учетом индивидуальной структуры последующей части адреса) не решается.. Разве что - ручками разобрать.
Вопрос упирается в проценты - сколько таких адресов.
Данная процедура сделана для упрощения обработки адресов, которые приносит клиент.
Это всеравно лучше, чем 2000 адресов разносить руками.

Проценты процентами, но я - немного про другое. Структура адреса на территории ru(cis) допускает любые вольности. Поэтому - воспринимать информацию из-под печатной машинки бесперспективно (2 andrey_anonymous даже если для разбора использовать классификатор). Вводить надо, используя классификатор..
23 май 07, 14:51    [4175043]     Ответить | Цитировать Сообщить модератору
 Re: Скрипт разбора адресной строки  [new]
andrey_anonymous
Member

Откуда: Москва
Сообщений: 18388
orawish
Вводить надо, используя классификатор..

Ну так я именно об этом и говорил... :)
23 май 07, 14:52    [4175058]     Ответить | Цитировать Сообщить модератору
 Re: Скрипт разбора адресной строки  [new]
Bely
Member

Откуда: Москва
Сообщений: 1903
orawish
еще напр. Чертаново-Северное
Ну, батенька...
Это называется МКРОРАЙОН! :)
Он есть в КЛАДР.
770000000003497

Так что здесь проблем нету...
23 май 07, 14:59    [4175108]     Ответить | Цитировать Сообщить модератору
Между сообщениями интервал более 1 года.
 Re: Скрипт разбора адресной строки  [new]
Bely
Member

Откуда: Москва
Сообщений: 1903
Bely
Вот, занимался похожей проблемой - создал парсер адреса с разделенными через запятую.
Доделал только что, тестирование жизнью пока не было


В скрипте, как оказалось, не хватает пары типов.

CREATE OR REPLACE 
TYPE t_token IS OBJECT  
(tbeg NUMBER, 
 tend NUMBER, 
 ttyp CHAR
);
/

CREATE OR REPLACE 
TYPE t_table IS TABLE OF t_token NOT NULL;
/

1 мар 09, 23:18    [6874952]     Ответить | Цитировать Сообщить модератору
 Re: Скрипт разбора адресной строки  [new]
SQL*Plus
Member

Откуда: Россия, Москва
Сообщений: 8132
Хорошо, что почти через 2 года сие было замечено...
Спасибо!
2 мар 09, 11:01    [6875668]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Oracle Ответить