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

1import datetime 

2from collections.abc import Iterator 

3 

4import regex 

5from regex import Match 

6 

7from documents.plugins.date_parsing.base import DateParserPluginBase 

8from documents.regex import safe_regex_finditer 

9 

10 

11class RegexDateParserPlugin(DateParserPluginBase): 

12 """ 

13 The default date parser, using a series of regular expressions. 

14 

15 It is configured entirely by the DateParserConfig object 

16 passed to its constructor. 

17 """ 

18 

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 ) 

29 

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) 

41 

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 

54 

55 def parse(self, filename: str, content: str) -> Iterator[datetime.datetime]: 

56 """ 

57 Implementation of the abstract parse method. 

58 

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 ) 

66 

67 yield from self._process_content(content, self.config.content_date_order)