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

1import ipaddress 

2from typing import List, Optional 

3 

4from presidio_analyzer import Pattern, PatternRecognizer 

5 

6 

7class IpRecognizer(PatternRecognizer): 

8 """ 

9 Recognize IP address using regex. 

10 

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 """ 

16 

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 ] 

34 

35 CONTEXT = ["ip", "ipv4", "ipv6"] 

36 

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 ) 

54 

55 def invalidate_result(self, pattern_text: str) -> bool: 

56 """ 

57 Check if the pattern text cannot be validated as an IP address. 

58 

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