Coverage for presidio_analyzer / predefined_recognizers / country_specific / germany / de_bsnr_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 DeBsnrRecognizer(PatternRecognizer): 

7 r""" 

8 Recognizes German Betriebsstättennummer (BSNR). 

9 

10 The BSNR is a 9-digit practice / site-of-care number assigned by the 

11 regional Kassenärztliche Vereinigung (KV) to each approved practice 

12 location (Betriebsstätte) participating in the German statutory health 

13 insurance system. It appears in billing records, treatment documents, and 

14 statutory healthcare communications and reveals the treating facility, 

15 making it sensitive under DSGVO. 

16 

17 Legal basis: § 75 Abs. 7 SGB V (Sozialgesetzbuch Fünftes Buch). 

18 Standard: KBV-Richtlinie nach § 75 Abs. 7 SGB V zur Vergabe der Arzt-, 

19 Betriebsstätten-, Praxisnetz- sowie der Netzverbundnummern. 

20 Data protection: DSGVO Art. 9 (Gesundheitsdaten), BDSG § 22. 

21 

22 Format (9 digits): 

23 Pos 1–2: KV-Bereichskennzeichen (regional KV code, e.g. 02 Hamburg, 

24 06 Nordrhein, 14 Berlin) 

25 Pos 3–9: Laufende Nummer (sequential number assigned by KV) 

26 

27 Examples (fictitious): 021234568, 061789045, 141234567 

28 

29 Accuracy note: The BSNR has no public checksum, so the 9-digit pattern 

30 ``\\b\\d{9}\\b`` is inherently broad. Context words are therefore essential 

31 for reliable detection; the base confidence is set low (0.2) to prevent 

32 false positives in digits-only contexts. Because the BSNR and DE_LANR 

33 share the same 9-digit surface form, the LANR check digit (validated by 

34 DE_LANR) will score higher than an unvalidated BSNR match when both 

35 context types are absent – in practice, document context words reliably 

36 separate the two. Formal accuracy evaluation has not been performed on a 

37 labelled dataset. 

38 

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

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

41 :param supported_language: Language this recognizer supports 

42 :param supported_entity: The entity this recognizer can detect 

43 """ 

44 

45 PATTERNS = [ 

46 Pattern( 

47 "Betriebsstättennummer BSNR (9 digits)", 

48 r"\b\d{9}\b", 

49 0.2, 

50 ), 

51 ] 

52 

53 CONTEXT = [ 

54 "betriebsstättennummer", 

55 "betriebsstätten-nummer", 

56 "bsnr", 

57 "betriebsstätte", 

58 "praxisnummer", 

59 "arztpraxis", 

60 "praxis", 

61 "kassenärztliche vereinigung", 

62 "kv-nummer", 

63 "kv nummer", 

64 "praxisadresse", 

65 "praxisstandort", 

66 "nebenbetriebsstätte", 

67 "hauptbetriebsstätte", 

68 "behandlungsort", 

69 "vertragsarztpraxis", 

70 ] 

71 

72 def __init__( 

73 self, 

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

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

76 supported_language: str = "de", 

77 supported_entity: str = "DE_BSNR", 

78 name: Optional[str] = None, 

79 ): 

80 patterns = patterns if patterns else self.PATTERNS 

81 context = context if context else self.CONTEXT 

82 super().__init__( 

83 supported_entity=supported_entity, 

84 patterns=patterns, 

85 context=context, 

86 supported_language=supported_language, 

87 name=name, 

88 )