Jupyter中Regex提取指定日期格式失败,与regex101结果不符求助
Let's break down what's going wrong with your regex and how to fix it properly.
The Problem with Your Modified Regex
Your regex [^ ](?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)[a-z., -]*\d{4} has two critical issues that cause it to fail in pandas:
- The leading
[^ ]requires a non-space character immediately before the month. This means valid entries like"Feb 2009"(which start with the month at the string's beginning) won't match—there's no character before the month to satisfy[^ ]. - Even if there was a character before the month,
[^ ]would include that character in your match result, which you don't want (you only want the month-year pair).
While it might have seemed to work in regex101, that's likely because you were testing cases where a non-space character existed before the month, but it doesn't account for valid entries where the month starts the string.
The Correct Approach
We need to ensure we only match month-year pairs that don't have a preceding day number. A clean way to do this is with a negative lookbehind assertion, which checks that no digit comes right before the month. Here's the adjusted solution:
import pandas as pd df5 = pd.Series(["04/20/2009", "04/20/09", "4/20/09", "4/3/09", "Mar-20-2009", "Mar 20, 2009", "March 20, 2009", "Mar. 20, 2009", "Mar 20 2009", "20 Mar 2009","20 March 2009", "20 Mar. 2009", "20 March, 2009", "Mar 20th, 2009", "Mar 21st, 2009", "Mar 22nd, 2009", "Feb 2009", "Sep 2009", "Oct 2010", "6/2008","12/2009", "2009", "2010"]) # Corrected regex with negative lookbehind result = df5.str.extractall(r'(?P<date>(?<!\d)(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)[a-z.,]*\s*\d{4})') print(result)
Regex Breakdown
Let's unpack each part of the corrected regex:
(?<!\d): Negative lookbehind assertion—ensures there is no digit immediately before the month. This filters out entries like"20 Mar 2009"where a day number precedes the month.(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec): Matches full or abbreviated month names (e.g.,Mar,March).[a-z.,]*: Matches optional trailing characters in month names (like thechinMarchor the.inMar.), allowing zero or more of these characters.\s*: Matches zero or more whitespace characters between the month and year (handles spaces or no spaces, though your target uses a space).\d{4}: Matches the four-digit year.
Why This Works
- It correctly matches valid entries like
"Feb 2009","Sep 2009"because there's no digit before the month. - It ignores entries like
"20 Mar 2009"or"Mar 20, 2009"because either a digit precedes the month, or the pattern includes a day component.
内容的提问来源于stack exchange,提问作者Ananthu

