Комплекс Regex найти дату и время - PullRequest
0 голосов
/ 24 сентября 2018

Есть ли кто-нибудь, чтобы помочь мне со следующим:

Я пытаюсь найти конкретные строки даты и времени в тексте (для использования в VBA Word).В настоящее время работает со следующей строкой RegEx:

(?: ([0-9] {1,2}) [| -])? (? :( jan (?: Uari)? |февраль: | м (Руари?) (?: аа) к.т. | Апрель: | мэй | июнь (П?) (?: я) |? июль (?: я) |? август (: ustus?)?| sep (?: tember | t)? | okt (?: ober)? | nov (?: ember)? | dec (?: ember)?))? (?: | -)? (? (3) (?: вокруг | в |))? (?: ([0-9] {1,2}: [0-9] {1,2})? (?: uur | u | u)?)?

Проверенный вывод следующего текста:

  1. дата с около времени: 26 сентября 2016 года около 09: 00u
  2. дата с временем: 1 сентября 2016 года в 09: 00 uur
  3. дата и время u: 1 сен 2018 09:00 u
  4. время без даты: 08:30 uur
  5. дата со временем u: 1 сентября 2016 года09:00
  6. только время: 09: 00
  7. только месяц: янв
  8. месяц и год: фев 2019
  9. только день: 02
  10. только день с '-': 2-
  11. день и месяц: 2 января
  12. месяц год: январь 2018
  13. дата с '-': 2 февраля-2018 09: 00
  14. другой месяц: 01 сентября 2016
  15. полный месяц: 1 сентября 2018
  16. сокращеногод: июль '18

Правила:

  • дата, за которой следует время, действительна
  • дата, за которой следует текст 'около 'или' at ', за которым следует время, действительное
  • дата без номера дня действительна
  • дата без года действительна
  • дата, месяц только не действительный
  • день, без месяца или года не действительный
  • дата может содержать тире '-'
  • годможет быть кратким с ', например jun '18
  • название месяца может быть коротким или длинным
  • полное совпадение включает' uur 'или' u '(для выделения текста в ms-Word)
  • текстовые совпадения из захвата без пробелов и пробелов

пример по адресу: [https://regex101.com/r/6CFgBP/1/]

Ожидаемый вывод (при использовании в VBA Word): Регулярное выражение Сопоставляет объект коллекции, в котором каждый Match.SubMatches содержит отдельные элементы d, m, y, hh: mm из групп захвата в строке поиска регулярного выражения.Например, 1: подсовпадения (или группы захвата) содержат значения: '26', 'sep', '2016', '09:00'

RegEx работает нормально, но некоторые ложноположительные значения нужныдля исключения:

  • В случае наличия дня без месяца / года следует исключить из регулярного выражения (пример 9 и 10)
  • В случае наличия месяца без дня,должен быть исключен (пример 7)

(я пытался с сомом смотреть в будущее и ссылками \ 1 и? (1), но не смог запустить его правильно ...)

Любой совет высоко ценится!

Ответы [ 2 ]

0 голосов
/ 24 сентября 2018

Наконец я нашел кое-что, что помогает мне правильно использовать месяц: -)

\b(?:([1-3]|[0-3]\d)[ |-](?'month'(?:[1-9]|\d[12])|(?:jan(?:uari)?|feb(?:ruari)?|m(?:aa)?rt|apr(?:il)?|mei|jun(?:i)?|jul(?:i)?|aug(?:ustus)?|sep(?:tember|t)?|okt(?:ober)?|nov(?:ember)?|dec(?:ember)?))?)?(?:(\g'month')[ |-]((?:19|20|\')(?:\d{2})))?\b(?: omstreeks | om | )?(?:(\d{1,2}[:]\d{2}(?: uur|u)?|[0-2]\d{3}(?: uur|u)))?\b

Используется именованный конструктор / подпрограмма.Найдено здесь: https://www.regular -expressions.info / subroutine.html

0 голосов
/ 24 сентября 2018

Как я понял, вам требуется, чтобы каждая часть даты / времени (день, месяц, год, час и минута) должна присутствовать .

Итак, выследует удалить ? после соответствующих групп (они не необязательны).

Рекомендуется также, чтобы каждая группа была зарегистрирована как соответствующая группа захвата .

Нет необходимости писать что-то вроде jun(?:i)?.Достаточно (и легче читать), когда вы пишете только juni? (? относится только к предшествующему i).

Еще один совет: поскольку язык регулярных выражений содержит \d класс char,используйте только его вместо [0-9] (регулярное выражение короче и его легче читать.

Необязательные части (в / вокруг) должны быть необязательной группой без захвата.

Что-нибудь послеминутная часть не требуется в регулярном выражении.

Поэтому я предлагаю регулярное выражение, как показано ниже (для удобства чтения я разделил его на строки):

(\d{1,2})[ -](jan(?:uari)?|feb(?:ruari)?|m(?:aa)?rt|apr(?:il)?|mei|juni?
|juli?|aug(?:ustus)?|sep(?:tember|t)?|okt(?:ober)?|nov(?:ember)?|dec(?:ember)?)
[ -](\d{4}) (?:around |at )?(\d{1,2}:\d{1,2})

Подробности:

  • (\d{1,2}) - День.
  • [ -] - Разделитель после дня (пробел или минус).
  • (jan(?:uari)?|...dec(?:ember)?) - Месяц.
  • [ -] - Разделитель после месяца.
  • (\d{4}) - год.
  • (?:around |at )? - Собственно, 3 варианта разделителя между годом и часом (пробел / около / в ), обратите внимание на пробел перед (...)? .
  • (\d{1,2}:\d{1,2}) - Час и минута.

Соответствует вариантам 1, 2, 3, 5и 13. Все остальные не содержат каждой требуемой части, поэтому они не совпадают.

Если вы разрешите, например, что часть часа / минуты является необязательной, измените соответствующий фрагмент на:

( (?:around |at )?(\d{1,2}:\d{1,2}))?

т.е. окружите пространство / около / в / час / минуту с помощью ( и )?, делая эту часть дополнительной группой.Затем также будут сопоставлены варианты 14 и 15.

Еще одно расширение: если вы также разрешите час / минуту часть только , добавьте |(\d{1,2}:\d{1,2}) кregex (all before - первый вариант, а добавленная часть - второй вариант только для час / минута .

Тогда ваши варианты № 4 и 6 также будут сопоставлены.

Рабочий пример см. https://regex101.com/r/33t1ps/1

Редактировать

Следуя вашему списку правил, я предлагаю следующее регулярное выражение:

  • (\d{1,2}[ -])? - День+ разделитель, необязательный.
  • (jan(?:uari)?|...|dec(?:ember)?) - Месяц.
  • (?:[ -](\d{4}|'\d{2}))? - Разделитель + год (4 или 2 цифры с «»).
  • ( (?:around |at )?(\d{1,2}:\d{1,2}))? - Разделитель + час / минута - необязательный конец варианта 1.
  • |(\d{1,2}:\d{1,2}) - Вариант 2 - только час и минута.

Не соответствует только вашим вариантам № 9и 10.

Полное регулярное выражение, включая также "uur", см. https://regex101.com/r/33t1ps/3

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...