T
T
tatarrr952019-09-25 16:29:23
PHP
tatarrr95, 2019-09-25 16:29:23

How to extract date from text?

I am writing a robot that recognizes speech. The robot asks the person for the date of birth, you need to recognize it. Phrases can be:
"I was born on June 2, 1745" (06/02/1745)
"date February 3, 94" (02/03/1994)
"24 0 5 1996" (05/24/1996)
"0 6 12 78" (12/06/1978)
"7 8 94" (08/07/1994)
Are there any ready-made solutions for this task? I think here you can easily do without neural networks. Naturally, the question is how to get the date from the processed text string, and not translate, recognize speech, etc.

Answer the question

In order to leave comments, you need to log in

3 answer(s)
T
tatarrr95, 2019-10-08
@tatarrr95

I wrote a php function that solves my problem without neural networks. There are date variants that cannot be uniquely recognized, then two date variants are returned.

function dateBirth($inputString){
            $inputString = str_replace(" январ", " 01", $inputString);
            $inputString = str_replace(" феврал", " 02", $inputString);
            $inputString = str_replace(" март", " 03", $inputString);
            $inputString = str_replace(" апрел", " 04", $inputString);
            $inputString = str_replace(" май", " 05", $inputString);
            $inputString = str_replace(" мая", " 05", $inputString);
            $inputString = str_replace(" мае", " 05", $inputString);
            $inputString = str_replace(" июн", " 06", $inputString);
            $inputString = str_replace(" июл", " 07", $inputString);
            $inputString = str_replace(" август", " 08", $inputString);
            $inputString = str_replace(" сентябр", " 09", $inputString);
            $inputString = str_replace(" октабр", " 10", $inputString);
            $inputString = str_replace(" ноябр", " 11", $inputString);
            $inputString = str_replace(" декабр", " 12", $inputString);
            $inputString = preg_replace('/\D/', '', $inputString);
            $year = "error";
            $daymonth = "";
            // Если длина строки больше 8 или меньше 4, вычислить дату не сможем
            if(strlen($inputString) < 4 || strlen($inputString) > 8){
                return false;
                
            }
            if(strlen($inputString) >= 6){ // если длина больше или равна 6, то год равен 4 числам
                if(intval(substr($inputString, -4)) > 1920){ //4 последних числа должны быть больше 1920, иначе это не год
                    $year = substr($inputString, -4);
                    $daymonth = substr($inputString, 0, -4);
                }
                if(strlen($inputString) == 6){ //если прошлое не год, значит год состоит из двух чисел, но тогда длина все строки не может быть длинее 6
                    if(intval("19".substr($inputString, -2)) > 1920){ //Проверяем, больше ли эти два числа чем 1920
                        $year = "19".substr($inputString, -2);
                        $daymonth = substr($inputString, 0, -2);
                    }
                }
            }
            else{
                if(intval("19".substr($inputString, -2)) > 1920){ //Если длина меньше 6, значит год из двух числел
                    $year = "19".substr($inputString, -2); //проверяем, больше ли год чем 1920
                    $daymonth = substr($inputString, 0, -2);
                }
            }
            // ищем день и месяц
            if($year != "error"){
                if(strlen($daymonth) == 4 || strlen($daymonth) == 2){ //если деньмесяц состоит из 2 или 4 чисел. бьем строку пополам и получаем день + месяц
                    $day = substr($daymonth, 0, -strlen($daymonth)/2);
                    $month = substr($daymonth, -strlen($daymonth)/2);
                }
                // Если деньмесяц состоит из 3 чисел, то сложно
                if(strlen($daymonth) == 3){
                    // Если первый 0, то день полюбому состоит из двух цифр
                    if(substr($daymonth, 0, 1) == "0"){ 
                        $day = substr($daymonth, 0, 2);
                        $month = substr($daymonth, -1);
                    }
                    // Если по середине 0, 1, 2 , то поулучается вилка, возвращаем сразу 2 вариианта
                    else if(substr($daymonth, 1, 1) == "0" || substr($daymonth, 1, 1) == "1" || substr($daymonth, 1, 1) == "2"){
                        $day = [substr($daymonth, 0, 1), substr($daymonth, 0, 2)]; //массив двух варантов дней
                        $month = [substr($daymonth, 1, 2), substr($daymonth, 2, 1)]; //массив двух вариантов месяцев
                        // проверяем, корректные ли дни и месяцы в массиве. Если нет, то превращаем массивы в немассивы без некорректных данных. Чтобы этим способом не проверить немассив, проверяем, массив ли это
                        if((intval($day[0]) > 31 || intval($month[0]) > 12 || intval($day[0]) == 0 || intval($month[0]) == 0) && is_array($day) && is_array($month)){
                            $day = $day[1];
                            $month = $month[1];
                        }
                        if((intval($day[1]) > 31 || intval($month[1]) > 12 || intval($day[1]) == 0 || intval($month[1]) == 0) && is_array($day) && is_array($month)){
                            $day = $day[0];
                            $month = $month[0];
                        }
                    }
                    // Если по середине 3
                    else if(substr($daymonth, 1, 1) == "3" && (substr($daymonth, 2, 1) == "1" || substr($daymonth, 2, 1) == "0")){
                        $day = [substr($daymonth, 0, 1), substr($daymonth, 0, 2)]; //массив двух варантов дней
                        $month = [substr($daymonth, 1, 2), substr($daymonth, 2, 1)]; //массив двух вариантов месяцев
                        // проверяем, корректные ли дни и месяцы в массиве. Если нет, то превращаем массивы в немассивы без некорректных данных. Чтобы этим способом не проверить немассив, проверяем, массив ли это
                        if((intval($day[0]) > 31 || intval($month[0]) > 12 || intval($day[0]) == 0 || intval($month[0]) == 0) && is_array($day) && is_array($month)){
                            $day = $day[1];
                            $month = $month[1];
                        }
                        if((intval($day[1]) > 31 || intval($month[1]) > 12 || intval($day[1]) == 0 || intval($month[1]) == 0) && is_array($day) && is_array($month)){
                            $day = $day[0];
                            $month = $month[0];
                        }
                    }
                    // Теперь просто двигаем точку с одного места ну другое проверяя, меньше ли день 31 и месяц 12. Если попали то круть
                    else{
                        // проверяем корректность данных при передвижении
                        if(intval(substr($daymonth, 0, 2)) <= 31 && intval(substr($daymonth, 0, 2)) != 0){
                            $day = substr($daymonth, 0, 2);
                            $month = substr($daymonth, -1);
                        }
                        // проверяем корректность данных при передвижении
                        else if(intval(substr($daymonth, 1, 2)) <= 12 && intval(substr($daymonth, 1, 2)) != 0 ){
                            $day = substr($daymonth, 0, 1);
                            $month = substr($daymonth, 1, 2);
                        }
                        else{
                            $day = "error";
                            $month = "error";
                        }
                    }

                }
            }
            $dataBorn = "";
            $format = 'd.m.Y';
            // Если в итоге у нас вернулось 2 варианта даты, работаем с ним
            if(is_array($day) && is_array($month)){
                $dataBorn = [$day[0].".".$month[0].".".$year , $day[1].".".$month[1].".".$year];
                $date = [];
                // пробуем законвертить дату и добавиить в массив, если не получается, значит хуевая дата
                try{
                    array_push($date, date_create_from_format($format, $dataBorn[0])->format('d.m.Y'));
                    // дополнительно проверяем на ошибки дату Например при конвертациии раньше 31.02.2016 выдавал не ошибку а 02.03.2016
                    if(DateTime::getLastErrors()['warning_count'] > 0) {
                        $date = "error";
                    }
                }
                catch (Error $e) {
                    $date = "error";
                }
                // пробуем законвертить дату и добавиить в массив, если не получается, значит хуевая дата
                try{
                    array_push($date, date_create_from_format($format, $dataBorn[1])->format('d.m.Y'));
                    // дополнительно проверяем на ошибки дату Например при конвертациии раньше 31.02.2016 выдавал не ошибку а 02.03.2016
                    if(DateTime::getLastErrors()['warning_count'] > 0) {
                        $date = "error";
                    }
                }
                catch (Error $e) {
                    $date = "error";
                }
                // Проверяем, остался ли массив после предыдущих манипуляций, и если в нем всего одно значение, переделываем массив в строку
                if(is_array($date) && count($date) < 2){
                    $date = $date[0];
                }
                return $date;
            }
            // Если вернулась всего одна дата
            else{
                // Проверяем на корректность день месяц
                if(intval($day) > 31 || intval($month) > 12 || intval($day) == 0 || intval($month) == 0){
                    $day = "error";
                    $month = "error";
                }
                $dataBorn = $day.".".$month.".".$year;
                // Продуем законвертииться в дату, если не получиилось, хуевая дата
                try {
                    $date = date_create_from_format($format, $dataBorn)->format('d.m.Y');
                    // дополнительно проверяем на ошибки дату Например при конвертациии раньше 31.02.2016 выдавал не ошибку а 02.03.2016
                    if(DateTime::getLastErrors()['warning_count'] > 0) {
                        $date = "error";
                    }
                } 
                catch (Error $e) {
                    $date = "error";
                }
                return $date;
            }
        }

Use as
dateBirth("текст текст текст 29.6.95 текст")

A
Antonio Solo, 2019-09-25
@solotony

parse syntactically correct dates - Carbon::parse
and parse
"I was born on June 2, 1745" (06/02/1745)
"date February 3, 94" (02/03/1994)
"24 0 5 1996" (05/24/1996)
"0 6 12 78 "(12/06/1978)
" 7 8 94 "(08/07/1994)
without a neural network it is unlikely to work out
02/03/19
- what's this?
March 2, 2019 ?
February 3, 2019 ?
March 19, 2002 ?
a 02-03-19

R
Randewoo, 2019-09-25
@Randewoo

Yes, neural networks are clearly needed here!
Contact the Bauman students, maybe someone wants to play tricks and take the order.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question