Coverage for presidio_analyzer / predefined_recognizers / country_specific / us / us_driver_license_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# List from https://ntsi.com/drivers-license-format/ 

6# --------------- 

7 

8# WA Driver License number is relatively unique as it also 

9# includes '*' chars. 

10# However it can also be 12 letters which makes every 12 letter' 

11# word a match. Therefore we split WA driver license 

12# regex: r'\b([A-Z][A-Z0-9*]{11})\b' into two regexes 

13# With different weights, one to indicate letters only and 

14# one to indicate at least one digit or one '*' 

15 

16 

17class UsLicenseRecognizer(PatternRecognizer): 

18 """ 

19 Recognizes US driver license using regex. 

20 

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

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

23 :param supported_language: Language this recognizer supports 

24 :param supported_entity: The entity this recognizer can detect 

25 """ 

26 

27 PATTERNS = [ 

28 Pattern( 

29 "Driver License - Alphanumeric (weak)", 

30 r"\b([A-Z][0-9]{3,6}|[A-Z][0-9]{5,9}|[A-Z][0-9]{6,8}|[A-Z][0-9]{4,8}|[A-Z][0-9]{9,11}|[A-Z]{1,2}[0-9]{5,6}|H[0-9]{8}|V[0-9]{6}|X[0-9]{8}|A-Z]{2}[0-9]{2,5}|[A-Z]{2}[0-9]{3,7}|[0-9]{2}[A-Z]{3}[0-9]{5,6}|[A-Z][0-9]{13,14}|[A-Z][0-9]{18}|[A-Z][0-9]{6}R|[A-Z][0-9]{9}|[A-Z][0-9]{1,12}|[0-9]{9}[A-Z]|[A-Z]{2}[0-9]{6}[A-Z]|[0-9]{8}[A-Z]{2}|[0-9]{3}[A-Z]{2}[0-9]{4}|[A-Z][0-9][A-Z][0-9][A-Z]|[0-9]{7,8}[A-Z])\b", 

31 0.3, 

32 ), 

33 Pattern( 

34 "Driver License - Digits (very weak)", 

35 r"\b([0-9]{6,14}|[0-9]{16})\b", 

36 0.01, 

37 ), 

38 ] 

39 

40 CONTEXT = [ 

41 "driver", 

42 "license", 

43 "permit", 

44 "lic", 

45 "identification", 

46 "dls", 

47 "cdls", 

48 "lic#", 

49 "driving", 

50 ] 

51 

52 def __init__( 

53 self, 

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

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

56 supported_language: str = "en", 

57 supported_entity: str = "US_DRIVER_LICENSE", 

58 name: Optional[str] = None, 

59 ): 

60 patterns = patterns if patterns else self.PATTERNS 

61 context = context if context else self.CONTEXT 

62 super().__init__( 

63 supported_entity=supported_entity, 

64 supported_language=supported_language, 

65 patterns=patterns, 

66 context=context, 

67 name=name, 

68 )