Я предлагаю использовать пользовательские di git границы ((?<!\d)
lookbehind и (?!\d)
lookahead), чтобы убедиться, что вы соответствуете только числам по вашему выбору, и убедитесь, что вы соответствуете годам , а не только 4-значные git числа, такие как 9873
с (?:19|20)\d{2}
группой без захвата с оператором чередования + любые две цифры. Дни можно сопоставить, как в ответе Яна , с шаблоном (?:0?[1-9]|1[0-2])
.
После извлечения дат с помощью str.extract
вы можете привести их к дате с помощью pd.to_datetime
.
С помощью .fillna()
вы можете манипулировать записями без совпадений (я оставил их пустыми в приведенном ниже коде).
Регулярное выражение равно
(?<!\d)((?:0?[1-9]|1[0-2])-(?:19|20)\d{2})(?!\d)
См. Регулярное выражение демо . Детали:
(?<!\d)
- отрицательный вид сзади, который не соответствует совпадению, если непосредственно слева от текущего местоположения есть ди git ((?:0?[1-9]|1[0-2])-(?:19|20)\d{2})
- Группа захвата 1 (требуется для str.extract
): (?:0?[1-9]|1[0-2])
- необязательно 0
и ди git от 1
до 9
или 1
, а затем 0
, 1
или 2 (so, numbers from
1 to
12`) -
- дефис (?:19|20)\d{2}
- 19
или 20
, а затем любые 2 цифры
(?!\d)
- отрицательный прогноз, который не дает совпадения, если сразу справа от текущего местоположения есть ди git.
Полный фрагмент:
import pandas as pd
df = pd.DataFrame()
data = { 'dob': ['will\t05-2020', 'John\t4-2020', 'James\t07-1999', 'Rob\t2-2001','kim\t1-20202020','Jane\t112-2020']}
df = pd.DataFrame(data)
df['Date'] = df['dob'].str.extract(r'(?<!\d)((?:0?[1-9]|1[0-2])-(?:19|20)\d{2})(?!\d)').fillna("")
df['Date'] = pd.to_datetime(df['Date'], format='%m%Y', errors='ignore')
Вывод:
>>> df
dob Date
0 will\t05-2020 05-2020
1 John\t4-2020 4-2020
2 James\t07-1999 07-1999
3 Rob\t2-2001 2-2001
4 kim\t1-20202020
5 Jane\t112-2020