Coverage for presidio_analyzer / predefined_recognizers / country_specific / germany / de_plz_recognizer.py: 100%

9 statements  

« prev     ^ index     » next       coverage.py v7.13.1, created at 2026-03-29 09:03 +0000

1from typing import List, Optional 

2 

3from presidio_analyzer import Pattern, PatternRecognizer 

4 

5 

6class DePlzRecognizer(PatternRecognizer): 

7 """ 

8 Recognizes German postal codes (Postleitzahl, PLZ). 

9 

10 German postal codes consist of exactly 5 digits in the range 01001–99998, 

11 assigned by Deutsche Post AG. A PLZ alone is generally not sufficient to 

12 identify a specific natural person and is therefore not directly personal data 

13 under DSGVO Art. 4 Nr. 1. However, in combination with other data (e.g., street 

14 address, name), it contributes to identifying an individual, and in very rural 

15 areas a single PLZ may cover only a handful of addresses. 

16 

17 Legal basis: DSGVO Art. 4 Nr. 1 in combination with other address data; BDSG. 

18 

19 Format: 

20 5 digits, 01001–99998 (boundary values 01000 and 99999 are excluded). 

21 Examples: 10115 (Berlin Mitte), 80331 (München), 22085 (Hamburg) 

22 

23 !! ACCURACY WARNING !! 

24 The pattern `[0-9]{5}` is extremely generic and will produce a very high number 

25 of false positives when used without context (e.g., year numbers, prices, order 

26 IDs, phone number fragments, reference numbers). The base confidence is 

27 therefore set to 0.05 – the recognizer is only actionable when strong context 

28 words such as "PLZ", "Postleitzahl" or "Postanschrift" are present nearby. 

29 This recognizer should only be enabled in pipelines where German address data 

30 is expected. Formal accuracy evaluation has not been performed on a labelled 

31 dataset. 

32 

33 :param patterns: List of patterns to be used by this recognizer 

34 :param context: List of context words to increase confidence in detection 

35 :param supported_language: Language this recognizer supports 

36 :param supported_entity: The entity this recognizer can detect 

37 """ 

38 

39 # Regex covers 01001–09999 (leading zero) and 10000–99998. 

40 # Does NOT match 00000 (not a valid PLZ), 01000, 99999, or 6-digit numbers. 

41 # Reference: Deutsche Post AG PLZ-Verzeichnis. 

42 PATTERNS = [ 

43 Pattern( 

44 "Postleitzahl (5 digits, very low base confidence – context required)", 

45 r"\b(?!01000\b|99999\b)(0[1-9]\d{3}|[1-9]\d{4})\b", 

46 0.05, 

47 ), 

48 ] 

49 

50 CONTEXT = [ 

51 "plz", 

52 "postleitzahl", 

53 "postanschrift", 

54 "adresse", 

55 "wohnort", 

56 "ort", 

57 "wohnanschrift", 

58 "lieferadresse", 

59 "rechnungsadresse", 

60 "straße", 

61 "strasse", 

62 "hausnummer", 

63 "postfach", 

64 "bundesland", 

65 "gemeinde", 

66 "stadt", 

67 "dorf", 

68 ] 

69 

70 def __init__( 

71 self, 

72 patterns: Optional[List[Pattern]] = None, 

73 context: Optional[List[str]] = None, 

74 supported_language: str = "de", 

75 supported_entity: str = "DE_PLZ", 

76 name: Optional[str] = None, 

77 ): 

78 patterns = patterns if patterns else self.PATTERNS 

79 context = context if context else self.CONTEXT 

80 super().__init__( 

81 supported_entity=supported_entity, 

82 patterns=patterns, 

83 context=context, 

84 supported_language=supported_language, 

85 name=name, 

86 )