Coverage for presidio_analyzer / predefined_recognizers / generic / ip_recognizer.py: 87%
15 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
1import ipaddress
2from typing import List, Optional
4from presidio_analyzer import Pattern, PatternRecognizer
7class IpRecognizer(PatternRecognizer):
8 """
9 Recognize IP address using regex.
11 :param patterns: List of patterns to be used by this recognizer
12 :param context: List of context words to increase confidence in detection
13 :param supported_language: Language this recognizer supports
14 :param supported_entity: The entity this recognizer can detect
15 """
17 PATTERNS = [
18 Pattern(
19 "IPv4",
20 r"\b(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b",
21 0.6,
22 ),
23 Pattern(
24 "IPv6",
25 r"\b(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\b",
26 0.6,
27 ),
28 Pattern(
29 "IPv6",
30 r"::",
31 0.1,
32 ),
33 ]
35 CONTEXT = ["ip", "ipv4", "ipv6"]
37 def __init__(
38 self,
39 patterns: Optional[List[Pattern]] = None,
40 context: Optional[List[str]] = None,
41 supported_language: str = "en",
42 supported_entity: str = "IP_ADDRESS",
43 name: Optional[str] = None,
44 ):
45 patterns = patterns if patterns else self.PATTERNS
46 context = context if context else self.CONTEXT
47 super().__init__(
48 supported_entity=supported_entity,
49 patterns=patterns,
50 context=context,
51 supported_language=supported_language,
52 name=name,
53 )
55 def invalidate_result(self, pattern_text: str) -> bool:
56 """
57 Check if the pattern text cannot be validated as an IP address.
59 :param pattern_text: Text detected as pattern by regex
60 :return: True if invalidated
61 """
62 try:
63 ipaddress.ip_address(pattern_text)
64 except ValueError:
65 return True