[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Помогите сделать сложную регулярку
mikolas
Добрый день есть текст в нем встречается время или диапазон времени в таком виде

текст в 23 часа текст
текст в 22:00 - 00:00 текст
текст с 21.00 до 03.00 текст
текст в 17 часов текст
текст с 17:30 до 20:00текст
текст с 21:00 по 03:00текст
текст 18:30-19:30текст
текст в 13. 00 текст
текст в 17.00 текст
текст в 7.00текст
время может начинаться с буквы "в" (текст в 17.00 или текст в17.00)
может содержать между часами и минутами : (18:30, 18 :30, 18 : 30, 18: 30)- или больше пробелов,

точку (18.30, 18 .30, 18 . 30, 18. 30)- или больше пробелов, в этом случае нужно исключить время где минуты не должны быть в диапозоне от 01-12. Исключаем дату, 00 может быть.

или пустое пространство ( в 13 00, в 13 00).

могут быть диапазоны времени( в 11.00 - 00.00, в 22.00 - 00.00, в 22:00- 00:00, 22:00 -00:00, 22:00 00:00, 22:00 00:00 ) если диапозон начинается на "в" значит изключение для дат не нужно? но если диапазон начинается с "c"(с21.00 до 03.00, с 21:00 до 03:00, с 21:00 по 03:00 ) тогда нужно опять исключить время где минуты находятся в диапазоне 1-12.

Встречаются и такое время (23 часа, в 17 часов).
Ну и вообще время может быть без пробелов к тексту (текст22:00текст). В общем кто может помогите пожалуйста.
Ron
Скорее всего это будет не одно регулярное выражение, а целый блок в составе микро-парсера. Корневая регулярка (входная) просто будет смотреть присутствуют ли числа в строке, для производительности. За ней пойдет блок определения что это за цифры такие, и как их "воспринимать".

Одной регуляркой такое если и можно сделать, то точно из разряда эпичных извращений. С крайне тяжелым процессом внесения правок (добавления формата).
mikolas
Ron, можете подсказать тогда на такие
18.30
18:30
18 30
23 часа
18 часов
7.00
ну так что бы учитывало всевозможные единичные пробелы 18: 30, 18 : 30, человек же ошибки совершает. Ну а там уже буду с этими данными работать, спасибо
mikolas
скажите как исключить из списка те у которых на конце " -","-"," до" ,"до" https://regex101.com/r/Mrh4YC/3
mikolas
ну вроде диапазон выбрал https://regex101.com/r/Mrh4YC/4 Скажите а как в таких случаях потом обрабатывать этот диапазон, я в смысле как получить из диапазона две даты начальную и конечную, что бы потом работать с ними.
mikolas
сделал вот так https://regex101.com/r/Mrh4YC/5 но в php выдает другой результат, что я не так делаю
$t = 'текст в 23 часа
текст в 22:00 - 00:00
текст с 21.00 до 03.00
текст в 17 часов
текст с 17:30 до 20:00
текст 18:30-19:30
текст в 13. 00
текст в 17.00
текст в 7.00
время может начинаться с буквы "в" (текст в 17.00 или текст в17.00)
может содержать между часами и минутами : (18:30, 18 :30, 18 : 30, 18: 30)- или больше пробелов,
точку (18.30, 18 .30, 18 . 30, 18. 30)- или больше пробелов, в этом случае нужно исключить время где минуты не должны быть в диапозоне от 01-12, исключаем дату 00 может быть,
или пустое пространство ( в 13 00, в 13 00).
могут быть диапазоны времени( в 11.00 - 00.00, в 22.00 - 00.00, в 22:00- 00:00, 22:00 -00:00, 22:00 00:00, 22:00 00:00 ) если диапозон начинается в значит изключение для дат не нужно но если диапазон начинается с "c"(с21.00 до 03.00, с 21:00 до 03:00, с 21:00 по 03:00 ) тогда нужно опять исключить время где минуты находятся в диапазоне 1-12.
Встречаются и такое время (23 часа, в 17 часов).
Ну и вообще время может быть без пробелов к тексту (текст22:00текст)'
;
//print__r($t);

print__r($t);
preg_match_all('~/[вс ]{0,3}([0-9]{1,2})[:. ]{1,3}([0-9]{1,2}|часа|часов)
(\sдо|до|по|\sпо|\s-|-)[\s]{0,1}([0-9]{1,2})[:. ]{1,3}([0-9]{1,2}|часа|часов)/ui'
,$t,$m);
print__r($m);
mikolas
все разобрался
killer8080
Цитата (mikolas @ 8.07.2017 - 18:18)
[:. ]{1,3}

плохое решение, в эту маску попадёт не только ' : ' как ты ожидаешь, но и другие комбинации, например ':::', ':.:' и т.д.
Цитата (mikolas @ 7.07.2017 - 17:58)
точку (18.30, 18 .30, 18 . 30, 18. 30)- или больше пробелов, в этом случае нужно исключить время где минуты не должны быть в диапозоне от 01-12. Исключаем дату, 00 может быть.

я бы вообще не стал использовать точку как разделитель времени, но если использовать, то оставить это на ручную модерацию, т.к. если это дата, то не ясно где там день, где месяц, где год, все слишком не определённо.
как вариант можно так
$t = 'текст в 23 часа 
текст в 22:00 - 00:00
текст с 21.00 до 03.00
текст в 17 часов
текст с 17:30 до 20:00
текст 18:30-19:30
текст в 13. 00
текст в 17.00
текст в 7.00
вот это не должно попасть 25:59 222:30 в 27 часа
время может начинаться с буквы "в" (текст в 17.00 или текст в17.00)
может содержать между часами и минутами : (18:30, 18 :30, 18 : 30, 18: 30)- или больше пробелов,
точку (18.30, 18 .30, 18 . 30, 18. 30)- или больше пробелов, в этом случае нужно исключить время где минуты
не должны быть в диапозоне от 01-12, исключаем дату 00 может быть,
или пустое пространство ( в 13 00, в 13 00).
могут быть диапазоны времени( в 11.00 - 00.00, в 22.00 - 00.00, в 22:00- 00:00, 22:00 -00:00, 22:00 00:00, 22:00 00:00 )
если диапозон начинается в значит изключение для дат не нужно но если диапазон начинается с "c"(с21.00 до 03.00, с 21:00 до 03:00, с 21:00 по 03:00 )
тогда нужно опять исключить время где минуты находятся в диапазоне 1-12.
Встречаются и такое время (23 часа, в 17 часов).
Ну и вообще время может быть без пробелов к тексту (текст22:00текст)'
;

$pattern = '~
(?P<fulltime> # полное время
(?P<hour1> (?<!\d)[0-1]?\d ) # часы от 00 до 19
(?:\ *[:.]\ *|\ +) # разделитель .:пробел
(?P<minute1> [0-5]\d ) # минуты от 00 до 59
|
(?P<hour2> (?<!\d)2[0-3] ) # часы от 20 до 23
(?:\ *[:.]\ *|\ +) # разделитель .:пробел
(?P<minute2> [0-5]\d ) # минуты от 00 до 59
)
|
(?: # только час (в 23 часа и т.п.)
(?P<hour3>
(?<!\d)[0-1]?\d # часы от 00 до 19
|
(?<!\d)2[0-3] # часы от 20 до 23
)
\ *час(?:а|ов)?\b
)
~iux'
;
echo '<pre>'.preg_replace_callback($pattern, function($m) {
if (!empty($m['fulltime'])) {
return '<span style="background-color:yellow; color:red;" title ="полное время">'.$m[0].'</span>';
} else {
return '<span style="background-color:green; color:yellow;" title ="только час">'.$m[0].'</span>';
}
}
, $t).'</pre>';
preg_match_all($pattern,$t,$m);
echo '<pre>';
print_r($m);
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.