Coverage for presidio_analyzer / predefined_recognizers / country_specific / india / in_pan_recognizer.py: 100%
10 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
1from typing import List, Optional, Tuple
3from presidio_analyzer import Pattern, PatternRecognizer
6class InPanRecognizer(PatternRecognizer):
7 """
8 Recognizes Indian Permanent Account Number ("PAN").
10 The Permanent Account Number (PAN) is a ten digit alpha-numeric code
11 with the last digit being a check digit calculated using a
12 modified modulus 10 calculation.
13 This recognizer identifies PAN using regex and context words.
14 Reference: https://en.wikipedia.org/wiki/Permanent_account_number,
15 https://incometaxindia.gov.in/Forms/tps/1.Permanent%20Account%20Number%20(PAN).pdf
17 :param patterns: List of patterns to be used by this recognizer
18 :param context: List of context words to increase confidence in detection
19 :param supported_language: Language this recognizer supports
20 :param supported_entity: The entity this recognizer can detect
21 :param replacement_pairs: List of tuples with potential replacement values
22 for different strings to be used during pattern matching.
23 This can allow a greater variety in input, for example by removing dashes or spaces.
24 """
26 PATTERNS = [
27 Pattern(
28 "PAN (High)",
29 r"\b([A-Za-z]{3}[AaBbCcFfGgHhJjLlPpTt]{1}[A-Za-z]{1}[0-9]{4}[A-Za-z]{1})\b",
30 0.5,
31 ),
32 Pattern(
33 "PAN (Medium)",
34 r"\b([A-Za-z]{5}[0-9]{4}[A-Za-z]{1})\b",
35 0.1,
36 ),
37 Pattern(
38 "PAN (Low)",
39 r"\b((?=.*?[a-zA-Z])(?=.*?[0-9]{4})[\w@#$%^?~-]{10})\b",
40 0.01,
41 ),
42 ]
44 CONTEXT = [
45 "permanent account number",
46 "pan",
47 ]
49 def __init__(
50 self,
51 patterns: Optional[List[Pattern]] = None,
52 context: Optional[List[str]] = None,
53 supported_language: str = "en",
54 supported_entity: str = "IN_PAN",
55 replacement_pairs: Optional[List[Tuple[str, str]]] = None,
56 name: Optional[str] = None,
57 ):
58 self.replacement_pairs = (
59 replacement_pairs if replacement_pairs else [("-", ""), (" ", "")]
60 )
61 patterns = patterns if patterns else self.PATTERNS
62 context = context if context else self.CONTEXT
63 super().__init__(
64 supported_entity=supported_entity,
65 patterns=patterns,
66 context=context,
67 supported_language=supported_language,
68 name=name,
69 )