Coverage for documents/plugins/date_parsing/regex_parser.py: 41%
21 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-10 09:07 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-10 09:07 +0000
1import datetime
2from collections.abc import Iterator
4import regex
5from regex import Match
7from documents.plugins.date_parsing.base import DateParserPluginBase
8from documents.regex import safe_regex_finditer
11class RegexDateParserPlugin(DateParserPluginBase):
12 """
13 The default date parser, using a series of regular expressions.
15 It is configured entirely by the DateParserConfig object
16 passed to its constructor.
17 """
19 DATE_REGEX = regex.compile(
20 r"(\b|(?!=([_-])))(\d{1,2})[\.\/-](\d{1,2})[\.\/-](\d{4}|\d{2})(\b|(?=([_-])))|"
21 r"(\b|(?!=([_-])))(\d{4}|\d{2})[\.\/-](\d{1,2})[\.\/-](\d{1,2})(\b|(?=([_-])))|"
22 r"(\b|(?!=([_-])))(\d{1,2}[\. ]+[a-zéûäëčžúřěáíóńźçŞğü]{3,9} \d{4}|[a-zéûäëčžúřěáíóńźçŞğü]{3,9} \d{1,2}, \d{4})(\b|(?=([_-])))|"
23 r"(\b|(?!=([_-])))([^\W\d_]{3,9} \d{1,2}, (\d{4}))(\b|(?=([_-])))|"
24 r"(\b|(?!=([_-])))([^\W\d_]{3,9} \d{4})(\b|(?=([_-])))|"
25 r"(\b|(?!=([_-])))(\d{1,2}[^ 0-9]{2}[\. ]+[^ ]{3,9}[ \.\/-]\d{4})(\b|(?=([_-])))|"
26 r"(\b|(?!=([_-])))(\b\d{1,2}[ \.\/-][a-zéûäëčžúřěáíóńźçŞğü]{3}[ \.\/-]\d{4})(\b|(?=([_-])))",
27 regex.IGNORECASE,
28 )
30 def _process_match(
31 self,
32 match: Match[str],
33 date_order: str,
34 ) -> datetime.datetime | None:
35 """
36 Processes a single regex match using the base class helpers.
37 """
38 date_string = match.group(0)
39 date = self._parse_string(date_string, date_order)
40 return self._filter_date(date)
42 def _process_content(
43 self,
44 content: str,
45 date_order: str,
46 ) -> Iterator[datetime.datetime]:
47 """
48 Finds all regex matches in content and yields valid dates.
49 """
50 for m in safe_regex_finditer(self.DATE_REGEX, content):
51 date = self._process_match(m, date_order)
52 if date is not None:
53 yield date
55 def parse(self, filename: str, content: str) -> Iterator[datetime.datetime]:
56 """
57 Implementation of the abstract parse method.
59 Reads its configuration from `self.config`.
60 """
61 if self.config.filename_date_order:
62 yield from self._process_content(
63 filename,
64 self.config.filename_date_order,
65 )
67 yield from self._process_content(content, self.config.content_date_order)