Регулярные выражения

За вознаграждение или нахаляву (если повезёт)

Модераторы: Хыиуду, dr.Jekill, MOTOCoder, Medved

Ответить
АлинаБалаева
Сообщения: 2
Зарегистрирован: 10 янв 2018, 16:37

Регулярные выражения

Сообщение АлинаБалаева » 10 янв 2018, 16:38

Добрый день, уважаемые форумчане!
Помогите, пожалуйста, решить проблему:
есть строка вида
143301, обл. Московская, г. Дмитров, ул. Сиреневая, д. 50
или
обл. Московская, г. Дмитров, ул. Сиреневая, д. 50
Ее нужно привести к такому виду:
Дмитров Сиреневая 50.
При этом вместо Московской области может быть любая другая, либо край, либо республика. Так же есть вероятность, что обозначения субъекта РФ впринципе не будет, что-то вроде "125009, г. Москва, ул. Тверская, д. 4". Вместо улицы может быть переулок, проезд, тупик, бульвар и т.д. Вместо города, соответственно, может быть любой другой, не факт, что город, но населенный пункт(г. , п. , с. , д. , etc).
Понимаю: задача может быть решена регулярными выражениями.
Не понимаю: регулярных выражений. Сижу с ними уже недели две. Мозг упорно отказывается вникнуть в материал.
Очень прошу, помогите! Голова скоро лопнет :(

dr.Jekill
Сообщения: 509
Зарегистрирован: 03 янв 2009, 23:17
Откуда: Voronezh
Контактная информация:

Сообщение dr.Jekill » 10 янв 2018, 18:12

Сделайте токенизацию по запятой. У Вас получится что-то вроде следующих частей:
143301
обл. Московская
г. Дмитров
ул. Сиреневая
д. 50
Далее проверяйте каждый токен по набору правил. Напр. индекс вообще можно легко отбросить по простому правилу - является ли токен числом, если да, то это индекс и его можно отбросить.
Нашли сущность (напр. индекс) пометили, что сущность данного типа найдена. Далее обрабатываете оставшиеся токены по правилам оставшихся сущностей.
Это если реализовать на основе правил без использования сторонних сервисов.
---
Так же для решения данной задачи можно использовать машинное обучение (named entity extraction, named entity recognition). Реализовать самому или использовать напр. dialogflow от гугл.

Вы какой язык программирования используете?
Нет религии выше истины

АлинаБалаева
Сообщения: 2
Зарегистрирован: 10 янв 2018, 16:37

Re: Регулярные выражения

Сообщение АлинаБалаева » 11 янв 2018, 14:46

Использую C#, но я начинающая, самоучка, читала Шилдта, но как-то не очень просто он пишет

dr.Jekill
Сообщения: 509
Зарегистрирован: 03 янв 2009, 23:17
Откуда: Voronezh
Контактная информация:

Re: Регулярные выражения

Сообщение dr.Jekill » 11 янв 2018, 18:43

Задача в целом, если делать на основе правил, не сложная и, думаю, Вы справитесь ) Ждём Вашего кода в теме
Нет религии выше истины

dr.Jekill
Сообщения: 509
Зарегистрирован: 03 янв 2009, 23:17
Откуда: Voronezh
Контактная информация:

Re: Регулярные выражения

Сообщение dr.Jekill » 11 янв 2018, 20:24

К сожалению синтаксис C# плохо помню. Вот сделал Вам небольшой пример на PHP:

Код: Выделить всё

<?php
    function isAnyParam($token, $keys, $part_after_key_must_num = false) {
        $finded = false;
        foreach($keys as $key) 
            if ($key != "")    {
                $pos = strpos($token, $key);
                if (($pos !== false) && ($pos == 0)) {
                    $part_after_key = substr($token, strlen($key));
                    if (is_numeric($part_after_key) == $part_after_key_must_num) {
                        $finded = true;
                        break;
                    }
                }
            } else if (is_numeric($token) == $part_after_key_must_num) {
                $finded = true;
                break;
            }
        return $finded;
    }

    $params = array(
            array(
                "name" => "Индекс", 
                "keys" => array(""),
                "part_after_key_must_num" => true,
                "finded" => false
            ),
            array(
                "name" => "Регион", 
                "keys" => array("обл. ", "край ",  "республика "),
                "part_after_key_must_num" => false,
                "finded" => false
            ),
            array(
                "name" => "Населенный пункт", 
                "keys" => array("г. ", "п. ", "с. ", "д. "),
                "part_after_key_must_num" => false,
                "finded" => false
            ),
            array(
                "name" => "Улица", 
                "keys" => array("ул. ", "переулок ", "проезд ", "тупик ", "бульвар "),
                "part_after_key_must_num" => false,
                "finded" => false
            ),
            array(
                "name" => "Дом", 
                "keys" => array("д. "),
                "part_after_key_must_num" => true,
                "finded" => false
            )
    );
    
    $s = '143301, обл. Тверская, д. Дмитровка, переулок Южный, д. 10';
    echo "<b>".$s."</b><hr />";
    
    $tokens = explode(',', $s);
    foreach($tokens as $token)
        foreach($params as &$param) 
            if (!$param["finded"]) 
                if (isAnyParam(trim($token), $param["keys"], $param["part_after_key_must_num"])) {
                    $param["finded"] = true;
                    echo $param["name"].": ".trim($token)."
";
                    break;
                }
?>
Результат работы скрипта:
143301, обл. Тверская, д. Дмитровка, переулок Южный, д. 10
Индекс: 143301
Регион: обл. Тверская
Населенный пункт: д. Дмитровка
Улица: переулок Южный
Дом: д. 10
Думаю идея понятная. После извлечения расставить параметры в необходимом Вам порядке не составит труда.

Ответить