inference.py 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. # Copyright (c) 2010-2024 openpyxl
  2. """
  3. Type inference functions
  4. """
  5. import datetime
  6. import re
  7. from openpyxl.styles import numbers
  8. PERCENT_REGEX = re.compile(r'^(?P<number>\-?[0-9]*\.?[0-9]*\s?)\%$')
  9. TIME_REGEX = re.compile(r"""
  10. ^(?: # HH:MM and HH:MM:SS
  11. (?P<hour>[0-1]{0,1}[0-9]{2}):
  12. (?P<minute>[0-5][0-9]):?
  13. (?P<second>[0-5][0-9])?$)
  14. |
  15. ^(?: # MM:SS.
  16. ([0-5][0-9]):
  17. ([0-5][0-9])?\.
  18. (?P<microsecond>\d{1,6}))
  19. """, re.VERBOSE)
  20. NUMBER_REGEX = re.compile(r'^-?([\d]|[\d]+\.[\d]*|\.[\d]+|[1-9][\d]+\.?[\d]*)((E|e)[-+]?[\d]+)?$')
  21. def cast_numeric(value):
  22. """Explicitly convert a string to a numeric value"""
  23. if NUMBER_REGEX.match(value):
  24. try:
  25. return int(value)
  26. except ValueError:
  27. return float(value)
  28. def cast_percentage(value):
  29. """Explicitly convert a string to numeric value and format as a
  30. percentage"""
  31. match = PERCENT_REGEX.match(value)
  32. if match:
  33. return float(match.group('number')) / 100
  34. def cast_time(value):
  35. """Explicitly convert a string to a number and format as datetime or
  36. time"""
  37. match = TIME_REGEX.match(value)
  38. if match:
  39. if match.group("microsecond") is not None:
  40. value = value[:12]
  41. pattern = "%M:%S.%f"
  42. #fmt = numbers.FORMAT_DATE_TIME5
  43. elif match.group('second') is None:
  44. #fmt = numbers.FORMAT_DATE_TIME3
  45. pattern = "%H:%M"
  46. else:
  47. pattern = "%H:%M:%S"
  48. #fmt = numbers.FORMAT_DATE_TIME6
  49. value = datetime.datetime.strptime(value, pattern)
  50. return value.time()