Страница 1 из 1

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

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

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

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

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

Добавлено: 11 янв 2018, 14:46
АлинаБалаева
Использую C#, но я начинающая, самоучка, читала Шилдта, но как-то не очень просто он пишет

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

Добавлено: 11 янв 2018, 18:43
dr.Jekill
Задача в целом, если делать на основе правил, не сложная и, думаю, Вы справитесь ) Ждём Вашего кода в теме

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

Добавлено: 11 янв 2018, 20:24
dr.Jekill
К сожалению синтаксис 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
Думаю идея понятная. После извлечения расставить параметры в необходимом Вам порядке не составит труда.