Regex To Alter Date String - PullRequest
       67

Regex To Alter Date String

0 голосов
/ 31 мая 2019

Я немного новичок в python, и для этого задания нас попросили использовать одно регулярное выражение для решения каждой подсказки. Я закончил подсказки A-C, но теперь я застрял на подсказке D. Вот подсказка:

д. Подстановка с использованием регулярного выражения, которая преобразует дату в формате «29 мая 2019 года» или «29 мая 2019 года» в «29 мая 19».

Допустимый формат даты для сопоставления имеет следующие элементы: • Месяц должен быть обычной трехбуквенной аббревиатурой месяца, начинающейся с заглавной буквы, за которой следуют две строчные буквы: январь, февраль, мар, апрель, май, июнь, июль, август, сентябрь, октябрь, ноябрь, декабрь
• День может состоять из одной или двух цифр. Нет необходимости проверять действительный день, допустимы даты с ведущими нулями, например 03. • Год ровно из четырех цифр.
• Месяц и день разделены одним или несколькими пробелами. День и год также разделены одним или несколькими пробелами, но необязательная запятая сразу после дня разрешена (пробелы между днем ​​и запятой не допускаются)

На чем я застрял: я не уверен, что поместить в выражение r "..." (см. Код), и теперь у меня появляется ошибка "re.error: bad escape \ w в позиции 0 ", если бы мы могли исправить ошибку или найти другой способ сделать это, поддерживая substr = r" ... ", я был бы очень признателен! Спасибо!

Примечание: - Мой код re.compile работает просто отлично, прежде чем я перепутал подстроку, чтобы изменить вывод, он принял случай. Он просто не конвертировал, так как я еще не написал строку конвертации. - В настоящий момент обработка дат не очень обычна, я планирую работать над этим после получения чего-то, что работает.

Код:

import re

d = re.compile(r"^((Jan)\s+[1-31],\s+\d{4})$|"
               r"^((Jan)\s+[1-31]\s+\d{4})$|"
               r"^((Feb)\s+[1-28],\s+\d{4})$|"
               r"^((Feb)\s+[1-28]\s+\d{4})$|"
               r"^((Feb)\s+[1-29],\s+\d{4})$|" #ask prof about leap years
               r"^((Feb)\s+[1-29]\s+\d{4})$|"  #ask prof about leap years
               r"^((Mar)\s+[1-31],\s+\d{4})$|"
               r"^((Mar)\s+[1-31]\s+\d{4})$|"
               r"^((Apr)\s+[1-30],\s+\d{4})$|"
               r"^((Apr)\s+[1-30]\s+\d{4})$|"
               r"^((May)\s+[1-31],\s+\d{4})$|"
               r"^((May)\s+[1-31]\s+\d{4})$|"
               r"^((Jun)\s+[1-30],\s+\d{4})$|"
               r"^((Jun)\s+[1-30]\s+\d{4})$|"
               r"^((Jul)\s+[1-31],\s+\d{4})$|"
               r"^((Jul)\s+[1-31]\s+\d{4})$|"
               r"^((Aug)\s+[1-31],\s+\d{4})$|"
               r"^((Aug)\s+[1-31]\s+\d{4})$|"
               r"^((Sep)\s+[1-30],\s+\d{4})$|"
               r"^((Sep)\s+[1-30]\s+\d{4})$|"
               r"^((Oct)\s+[1-31],\s+\d{4})$|"
               r"^((Oct)\s+[1-31]\s+\d{4})$|"
               r"^((Nov)\s+[1-30],\s+\d{4})$|"
               r"^((Nov)\s+[1-30]\s+\d{4})$|"
               r"^((Dec)\s+[1-31],\s+\d{4})$|"
               r"^((Dec)\s+[1-31]\s+\d{4})$")

subStr = r"\w\s\d{1,2}\s\d{4}"

print("----Part d tests that match (and should change):")
print(d.sub(subStr, "May 29, 2019"))

print("----Part d tests that match (and should remain unchanged):")
print(d.sub(subStr, "May 29 19"))

Ожидаемый результат:

----Part d tests that match (and should change):
May 29 19
----Part d tests that match (and should remain unchanged):
May 29 19

Фактический вывод (если я оставил подстроку пустой, и как она в настоящее время):

Blank:
----Part d tests that match (and should change):
May 29, 2019
----Part d tests that match (and should remain unchanged):
May 29 19

--------------------------------
Current:
----Part d tests that match (and should change):
    this = chr(ESCAPES[this][1])
KeyError: '\\w'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:/Users/Xavier/PycharmProjects/hw7/hw7.py", line 101, in <module>
    print(d.sub(subStr, "May 29, 2019"))
  File "C:\Users\Xavier\AppData\Local\Programs\Python\Python37\lib\re.py", line 309, in _subx
    template = _compile_repl(template, pattern)
  File "C:\Users\Xavier\AppData\Local\Programs\Python\Python37\lib\re.py", line 300, in _compile_repl
    return sre_parse.parse_template(repl, pattern)
  File "C:\Users\Xavier\AppData\Local\Programs\Python\Python37\lib\sre_parse.py", line 1024, in parse_template
    raise s.error('bad escape %s' % this, len(this))
re.error: bad escape \w at position 0

Ответы [ 2 ]

0 голосов
/ 31 мая 2019

Если использование регулярных выражений не является обязательным, я бы вместо этого использовал pandas.to_datetime или time.strptime:

панд

import pandas as pd

s = "Jun 29, 2019"

try:
   print(pd.to_datetime(s).strftime('%d %b %Y'))

except ValueError:
   print('unrecognized time format!')

%b означает сокращение месяца, полный список см. В документации .

время

или если у вас не установлены панды, используйте встроенную библиотеку time:

import time

out = None
for pattern in ['%b %d, %Y', '%b %d %Y']:
    try:
        out = time.strftime('%d %b %Y', time.strptime(s, pattern))
    except ValueError:
        continue

if out is None:
    print('Error: Could not read the time')

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

Если вам для этого нужно использовать регулярные выражения, вам нужно заменить [1-31] например, с (?:[12]\d|3[01]|\d), см. тестер регулярных выражений .

и тогда вы используете re.sub неправильно. Вы бы хотели вставить группы захвата в первое большое регулярное выражение, а затем использовать \1, \2, ... в строке замены, чтобы вернуть их обратно, поэтому \w

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

И единственный способ использования регулярных выражений и проверки дат был бы

(?:(Jan|Mar|May|Jul|Aug|Oct|Dec) (3[01]|[12]\d|\d)|(Apr|Jun|Sep|Nov) (30|[12]\d|\d)|(Feb) (2[0-9]|[1]\d|\d)),? (\d{4})

и использование

subStr = '\1\3\5 \2\4\6 \7'

, что невероятно безобразно и не относится к високосным годам.

0 голосов
/ 31 мая 2019

Подсказки:

  • (Jan|Feb|Mar) соответствует и фиксирует месяц ... продлить его на все месяцы.
  • Квадратные скобки соответствуют одному символу ... [1-31] isэффективно [123] ... диапазон 1-3 или 1 (избыточный).[0-9] или просто \d соответствует любой одной цифре.В требованиях сказано, что дата не нуждается в проверке, поэтому \d{1,2} (совпадение 1 или две цифры) должно быть допустимым.
  • ? используется для совпадения 0 или 1, поэтому ,? является необязательнымзапятая.
  • 4-значный год, но только последние два: \d{2}(\d{2}).
  • В строке совпадения должно быть три группы захвата.\n, где n - это номер группы, вставляет то, что было захвачено, поэтому замена - просто r'\2 \1 \3'.
...