Coverage for presidio_analyzer / predefined_recognizers / country_specific / us / us_mbi_recognizer.py: 100%
16 statements
« prev ^ index » next coverage.py v7.13.1, created at 2026-03-29 09:03 +0000
« prev ^ index » next coverage.py v7.13.1, created at 2026-03-29 09:03 +0000
1"""Recognizer for US Medicare Beneficiary Identifier (MBI)."""
3from typing import List, Optional
5from presidio_analyzer import Pattern, PatternRecognizer
8class UsMbiRecognizer(PatternRecognizer):
9 """Recognize US Medicare Beneficiary Identifier (MBI) using regex.
11 The MBI is an 11-character identifier used by Medicare. The format follows
12 specific rules defined by CMS (Centers for Medicare & Medicaid Services):
13 https://www.cms.gov/medicare/new-medicare-card/understanding-new-medicare-beneficiary-identifier-mbi
15 Format: C A AN N A AN N A A N N
16 Where:
17 - C = numeric character (0-9)
18 - A = alphabetic character (excluding S, L, O, I, B, Z)
19 - AN = alphanumeric character (numeric or alphabetic, excluding S, L, O, I, B, Z)
21 Position rules:
22 - Positions 1, 4, 7, 10, 11: numeric (0-9)
23 - Positions 2, 5, 8, 9: alphabetic
24 - Positions 3, 6: alphanumeric
26 Example: 1EG4-TE5-MK73 (dashes are for display only)
28 :param patterns: List of patterns to be used by this recognizer
29 :param context: List of context words to increase confidence in detection
30 :param supported_language: Language this recognizer supports
31 :param supported_entity: The entity this recognizer can detect
32 """
34 # Valid letters: A-Z excluding S, L, O, I, B, Z
35 # Valid letters are: A, C, D, E, F, G, H, J, K, M, N, P, Q, R, T, U, V, W, X, Y
36 VALID_LETTERS = "ACDEFGHJKMNPQRTUVWXY"
37 VALID_ALPHANUMERIC = "0-9ACDEFGHJKMNPQRTUVWXY"
39 # Regex building blocks
40 _NUM = "[0-9]"
41 _ALPHA = f"[{VALID_LETTERS}]"
42 _ALPHANUM = f"[{VALID_ALPHANUMERIC}]"
44 # Full MBI pattern:
45 # Pos: 1 2 3 4 5 6 7 8 9 10 11
46 # NUM ALPHA ALPHANUM NUM ALPHA ALPHANUM NUM ALPHA ALPHA NUM NUM
48 # Pattern without dashes (11 consecutive characters)
49 _MBI_NO_DASH = (
50 f"{_NUM}{_ALPHA}{_ALPHANUM}{_NUM}"
51 f"{_ALPHA}{_ALPHANUM}{_NUM}"
52 f"{_ALPHA}{_ALPHA}{_NUM}{_NUM}"
53 )
55 # Pattern with dashes in XXXX-XXX-XXXX format
56 _MBI_WITH_DASH = (
57 f"{_NUM}{_ALPHA}{_ALPHANUM}{_NUM}-"
58 f"{_ALPHA}{_ALPHANUM}{_NUM}-"
59 f"{_ALPHA}{_ALPHA}{_NUM}{_NUM}"
60 )
62 PATTERNS = [
63 Pattern(
64 "MBI (weak)",
65 rf"\b{_MBI_NO_DASH}\b",
66 0.3,
67 ),
68 Pattern(
69 "MBI (medium)",
70 rf"\b{_MBI_WITH_DASH}\b",
71 0.5,
72 ),
73 ]
75 CONTEXT = [
76 "medicare",
77 "mbi",
78 "beneficiary",
79 "cms",
80 "medicaid",
81 "hic", # Health Insurance Claim number (predecessor)
82 "hicn",
83 ]
85 def __init__(
86 self,
87 patterns: Optional[List[Pattern]] = None,
88 context: Optional[List[str]] = None,
89 supported_language: str = "en",
90 supported_entity: str = "US_MBI",
91 ):
92 patterns = patterns if patterns else self.PATTERNS
93 context = context if context else self.CONTEXT
94 super().__init__(
95 supported_entity=supported_entity,
96 patterns=patterns,
97 context=context,
98 supported_language=supported_language,
99 )